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