James Edward Gray II wrote:
> On Oct 11, 2005, at 3:27 PM, Robert Boone 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
> > 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

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

+---+---+---+


>
> > 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
> >   end
>
> if 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."