Hello,
I'm trying to learn ruby so I am making a tic tac toe game. It is
based
on the example the pugs example directory. I'm looking for advice on how
to
make the script more ruby like.
Thanks,
Robert
tic-tac-toe.rb (1.39 KB)
Hello,
I'm trying to learn ruby so I am making a tic tac toe game. It is
based
on the example the pugs example directory. I'm looking for advice on how
to
make the script more ruby like.
Thanks,
Robert
tic-tac-toe.rb (1.39 KB)
Hello,
I'm trying to learn ruby so I am making a tic tac toe game. It is
based
on the example the pugs example directory. I'm looking for advice on how
to
make the script more ruby like.
Well, let's have a peek:
#!/usr/bin/ruby
# Add the ability to more than one object
# out of a collection
class Array
def pick(num)
(0...self.length).step(num) do
>i> yield self[i...i+num]
end
end
end
Clever, I like that.
# Print Tic Tac Toe board
def print_board(b)
puts "+---+---+---+"
b.pick(3) do |x,y,z|
puts "| #{x} | #{y} | #{z} |"
puts "+---+---+---+"
end
end
Looks good here.
# Test if there is a winner on the board
def winner?(game_board)
winning_set = [[ 0, 1, 2 ],[ 3, 4, 5 ],[ 6, 7, 8 ],[ 0, 3, 6 ],
[ 1, 4, 7 ],[ 2, 5, 8 ],[ 0, 4, 8 ],[ 2, 4, 6 ]]
winning_set.each do |x|
test_set = game_board.values_at(x[0],x[1],x[2])
raise "has won!" if (test_set == %w{X X X} || test_set == %w{O O O})
end
end
WINS = [[ 0, 1, 2 ],[ 3, 4, 5 ],[ 6, 7, 8 ],[ 0, 3, 6 ],
[ 1, 4, 7 ],[ 2, 5, 8 ],[ 0, 4, 8 ],[ 2, 4, 6 ]]
def winner?( game_board )
WINS.any? do |win|
game_board.values_at(*win).join =~ /^([XO])\1\1$/ ? $1 : nil
end
end
# Build game board and fill it with .
board =
9.times do |x|
board << '.'
end
board = Array.new(0) { "." }
player = 'X'
choice = ''
used =print_board board
puts "Pick a number 1-9."
while board.any? {|square| square == '.' }
print "#{player}'s turn> "
choice = gets.chompexit if choice =~ /[Qq](?:uit)?/
choice = choice.to_i # might as well just convert it once
if used.any? {|number| number == choice.to_i}
if used.include? choice
puts "Number #{choice} has been used!"
next
elsif not (1..9).include?(choice.to_i)
puts "Out of range."
next
endused << choice.to_i
board[choice.to_i-1] = player
print_board boardbegin
winner?(board)
rescue => e
puts "#{player} #{e}"
exit
end
if winner = winner?
puts "#{winner} has won!"
end
player = (player == 'X') ? 'O': 'X'
endputs "Cat won the game."
Well, those are my ideas. Hope they help.
James Edward Gray II
On Oct 11, 2005, at 3:27 PM, Robert Boone wrote:
James Edward Gray II wrote:
> Hello,
> I'm trying to learn ruby so I am making a tic tac toe game. It is
> based
> on the example the pugs example directory. I'm looking for advice
> on how
> to
> make the script more ruby like.Well, let's have a peek:
> #!/usr/bin/ruby
>
> # Add the ability to more than one object
> # out of a collection
> class Array
> def pick(num)
> (0...self.length).step(num) do
> >i> yield self[i...i+num]
> end
> end
> endClever, I like that.
> # Print Tic Tac Toe board
> def print_board(b)
> puts "+---+---+---+"
> b.pick(3) do |x,y,z|
> puts "| #{x} | #{y} | #{z} |"
> puts "+---+---+---+"
> end
> endLooks good here.
> # Test if there is a winner on the board
> def winner?(game_board)
> winning_set = [[ 0, 1, 2 ],[ 3, 4, 5 ],[ 6, 7, 8 ],[ 0, 3, 6 ],
> [ 1, 4, 7 ],[ 2, 5, 8 ],[ 0, 4, 8 ],[ 2, 4, 6 ]]
> winning_set.each do |x|
> test_set = game_board.values_at(x[0],x[1],x[2])
> raise "has won!" if (test_set == %w{X X X} || test_set == %w{O
> O O})
> end
> endWINS = [[ 0, 1, 2 ],[ 3, 4, 5 ],[ 6, 7, 8 ],[ 0, 3, 6 ],
[ 1, 4, 7 ],[ 2, 5, 8 ],[ 0, 4, 8 ],[ 2, 4, 6 ]]def winner?( game_board )
WINS.any? do |win|
game_board.values_at(*win).join =~ /^([XO])\1\1$/ ? $1 : nil
end
end
class Array
def winner?
WINS.any? { |pat| a = self.values_at( *pat ).uniq
a == ["X"] || a == ["O"]
}
end
end
> # Build game board and fill it with .
> board =
> 9.times do |x|
> board << '.'
> end
9.times do
board << '.'
end
Or:
board = ( ". " * 9 ).split
board = Array.new(0) { "." }
After this, "print_board( board )" produces
On Oct 11, 2005, at 3:27 PM, Robert Boone wrote:
+---+---+---+
> player = 'X'
> choice = ''
> used =
>
> print_board board
>
> puts "Pick a number 1-9."
> while board.any? {|square| square == '.' }
> print "#{player}'s turn> "
> choice = gets.chomp
>
> exit if choice =~ /[Qq](?:uit)?/
exit if choice =~ /^[Qq]/
choice = choice.to_i # might as well just convert it once
> if used.any? {|number| number == choice.to_i}
if used.include? choice
> puts "Number #{choice} has been used!"
> next
> elsif not (1..9).include?(choice.to_i)
> puts "Out of range."
> next
> end
>
> used << choice.to_i
>
> board[choice.to_i-1] = player
> print_board board
>
> begin
> winner?(board)
> rescue => e
> puts "#{player} #{e}"
> exit
> endif winner = winner?
puts "#{winner} has won!"
end
That would have to be
if winner = winner?( board )
And it would print "true has won!"
if board.winner?
puts "#{player} has won!"
exit
end
> player = (player == 'X') ? 'O': 'X'
> end
>
> puts "Cat won the game."
An alternative:
require "enumerator"
def print_board( b )
puts "+---+---+---+"
b.each_slice(3) do |row|
puts "| #{row.join(' | ')} |"
puts "+---+---+---+"
end
end
See tomorrow's Ruby Quiz summary for a detailed explanation...
James Edward Gray II
On Oct 11, 2005, at 3:46 PM, James Edward Gray II wrote:
#!/usr/bin/ruby
# Add the ability to more than one object
# out of a collection
class Array
def pick(num)
(0...self.length).step(num) do
>i> yield self[i...i+num]
end
end
endClever, I like that.
# Print Tic Tac Toe board
def print_board(b)
puts "+---+---+---+"
b.pick(3) do |x,y,z|
puts "| #{x} | #{y} | #{z} |"
puts "+---+---+---+"
end
endLooks good here.