Learning ruby by make a simple game...

Discussion in 'Ruby' started by Robert Boone, Oct 11, 2005.

  1. Robert Boone

    Robert Boone Guest

    --=-0QjTykESxBTBvTz8ZNbf
    Content-Type: text/plain
    Content-Transfer-Encoding: 7bit

    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


    --=-0QjTykESxBTBvTz8ZNbf
    Content-Disposition: attachment; filename=tic-tac-toe.rb
    Content-Type: application/x-ruby; name=tic-tac-toe.rb
    Content-Transfer-Encoding: 7bit

    #!/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

    # Print Tic Tac Toe board
    def print_board(b)
    puts "+---+---+---+"
    b.pick(3) do |x,y,z|
    puts "| #{x} | #{y} | #{z} |"
    puts "+---+---+---+"
    end
    end

    # 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

    # Build game board and fill it with .
    board = []
    9.times do |x|
    board << '.'
    end

    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)?/

    if used.any? {|number| number == choice.to_i}
    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

    player = (player == 'X') ? 'O': 'X'
    end

    puts "Cat won the game."

    --=-0QjTykESxBTBvTz8ZNbf--
    Robert Boone, Oct 11, 2005
    #1
    1. Advertising

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

    > # 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.chomp
    >
    > exit 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
    > 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

    > player = (player == 'X') ? 'O': 'X'
    > end
    >
    > puts "Cat won the game."


    Well, those are my ideas. Hope they help.

    James Edward Gray II
    James Edward Gray II, Oct 11, 2005
    #2
    1. Advertising

  3. 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."
    William James, Oct 12, 2005
    #3
  4. 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
    >> 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.


    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
    James Edward Gray II, Oct 12, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. BlackHawke
    Replies:
    12
    Views:
    1,569
    Andrew Thompson
    Jan 26, 2004
  2. judith
    Replies:
    0
    Views:
    1,651
    judith
    Nov 1, 2006
  3. Hal Vaughan
    Replies:
    7
    Views:
    473
  4. Max Kubierschky
    Replies:
    10
    Views:
    1,846
    pabloreda
    Mar 31, 2007
  5. Advertiser for `2D Games Development Central`

    {Game Development} 2D Game Development Central

    Advertiser for `2D Games Development Central`, May 7, 2008, in forum: Java
    Replies:
    2
    Views:
    413
    RedGrittyBrick
    May 8, 2008
Loading...

Share This Page