3 Replies - 1230 Views - Last Post: 24 September 2013 - 04:42 AM Rate Topic: -----

#1 aryeetej  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 23-September 13

Tic Tac Toe Game Code help

Posted 23 September 2013 - 05:09 PM

Hey guys.. been working on this for a while and hope anyone can offer some help. Trying to code a tic tac toe game in Ruby but still getting some errors in the program. can anyone please help?
Is This A Good Question/Topic? 0
  • +

Replies To: Tic Tac Toe Game Code help

#2 modi123_1  Icon User is offline

  • Suitor #2
  • member icon



Reputation: 9097
  • View blog
  • Posts: 34,181
  • Joined: 12-June 08

Re: Tic Tac Toe Game Code help

Posted 23 September 2013 - 05:11 PM

I would suggest showing us your current code and error message texts.. You know.. so folks know what to help you with.
Was This Post Helpful? 0
  • +
  • -

#3 aryeetej  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 23-September 13

Re: Tic Tac Toe Game Code help

Posted 23 September 2013 - 05:28 PM

class TicTacToeGame


  #---------->>>>>
  #Revised Game Update with Fixes (No Debug Statements)
  #When debugging a program, it is often helpful to include PUT statements within a DATA step,
  #in order to list the values of one or more variables in the log window.
  def initialize
    @master_hash = {
      'XXX'=>'winner_X',
      'OOO'=>'winner_O',
      'XX '=>'last_value_win',
      'X X'=>'middle_value_win',
      ' XX'=>'first_value_win',
      'OO ' =>'last_value_block',
      'O O'=>'middle_value_block',
      ' OO'=>'first_value_block',
      'X  '=>'last_two_values_add',
      ' X '=>'either_end_values_add',
      '  X'=>'first_two_values_add'}   #!!! values was in singular (no s). I added s.
  
  
    @game_board = { 
      "11"=>" ",
      "12"=>" ",
      "13"=>" ",
      "21"=>" ",
      "22"=>" ",
      "23"=>" ",
      "31"=>" ",
      "32"=>" ",
      "33"=>" " }
  
    @senarios = [ 
      "11","12","13",   # index 0
      "21","22","23",   # index 1
      "31","32","33",   # index 2
      "11","21","31",   # index 3
      "12","22","32",   # index 4
      "13","23","33",   # index 5
      "11","22","33",   # index 6
      "13","22","31" ]  # index 7
  
    @players = { :X => 'X', :o/>/> => 'O' }
    @turn = :X
  end

  # ---------->>>>>

  def game_play
    winner_flag = false
    9.times do
      if @turn == :X
        board_display                           #>>>
        player_choice                           #>>>
      else    
        computer_choice                         #>>>
      end                                       #>>>
      winner = game_winner?                     #!!! changed this section to allow for both winners (not a bug, just conceptual)
      if winner                                 #!!! this can be nil or winner_O/X
        board_display                           
        puts "The winner is:" + winner          #!!! the previous code assume that X was the only winner
        winner_flag = true
        break
      end
      @turn = (@turn == :X) ?  :o/>/> : :X 
    end
    if (!winner_flag)
      board_display                             #>>>
      puts "This game has been a draw"          #!!! removed "try again" - there needs to be an "gets" and a loop for that
     end
  end

  # ---------->>>>>

  private

  def player_choice                             #!!! there was logical error in the calls to the defs at the bottom of your code.
                                                #!!! after an error, the input question was repeated again and again
    def get_input(txt)                          #!!! since input is only used in player choice, I've put the block inside
      player_choice=0
      until (1..3) === player_choice do
        puts "Please enter the " + txt + " number (1,2, or 3): "
        player_choice = gets.chomp.to_i
        unless (1..3) === player_choice 
          puts "Your entry must be a number 1,2, or 3. Please try again."
        end
      end
      player_choice
    end
    
    player_choice_row = get_input("row")        
    player_choice_column = get_input("column")  
    location = (player_choice_row.to_s)+(player_choice_column.to_s)
    unless @game_board.values_at(location) == [" "]
      puts "That location is already occupied. Let's try again."
      player_choice
    end
    marker_placement_hash(location, 'X')
    marker_placement_array(location, 'X')

  end

  #---------->>>>>

  def computer_choice                                          #!!! I have included the strategy blocks inside the computer_choice
                                                               #!!! it reflets the scope and avoids having too many 'lose' blocks
                                                               #!!! at the class level. Helps readiblity.
    def go_for_the_win(value, times)
      location = nil
      trio = @senarios.each_slice(3)
      if value == 'last_value_win'
        location = trio.to_a[times].values_at(2)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'middle_value_win'
        location = trio.to_a[times].values_at(1)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'first_value_win'
        location = trio.to_a[times].values_at(0)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      end
    end
  
    def perform_block(value, times)
      location = nil
      trio = @senarios.each_slice(3)
      if value == 'last_value_block'
        location = trio.to_a[times].values_at(2)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'middle_value_block'
        location = trio.to_a[times].values_at(1)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'first_value_block'
        location = trio.to_a[times].values_at(0)[0]            #!!! this statement returns a one element array. So we need its contents [0]
      end
    end
  
    def add_to_existing(value, times)
      location = nil
      trio = @senarios.each_slice(3)
      puts value.class.name
      if value == 'last_two_values_add'
        location = trio.to_a[times].values_at([1,2].sample)[0] #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'either_end_values_add'
        location = trio.to_a[times].values_at([0,2].sample)[0] #!!! this statement returns a one element array. So we need its contents [0]
      elsif value == 'first_two_values_add'
        location = trio.to_a[times].values_at([0,1].sample)[0] #!!! this statement returns a one element array. So we need its contents [0]
      end
    end
  
    def random_move
      avail_moves = @game_board.delete_if {|key, value| $value != ' '}
      if avail_moves.has_key?("22")
        location = "22"
      else
        location = avail_moves.keys.sample
      end
      location
    end

    #!!! here is the actual code for computer_choice
    #!!! the logic was sequential in your code but it needed to be nested
    value, times = finding_patterns
    location = go_for_the_win(value, times)
    if location == nil
      location = perform_block(value, times)
      if location == nil  #!!! debug statement
        location = add_to_existing(value, times)
        if location == nil
          location = random_move
        end
      end
    end
    marker_placement_hash(location, 'O')
    marker_placement_array(location, 'O')
  end                                                   #!!! one end to many

  #---------->>>>>

  def marker_placement_hash(location, marker)
    @game_board[location] = marker
  end

  def marker_placement_array(location, marker)
    @senarios.map! do |element|
      if (element == location)
        marker
      else
        element
      end
    end
  end                                                 #!!! end was missing
  #---------->>>>>

  def board_display
    puts
    puts "| #{@game_board["11"]} | #{@game_board["12"]} | #{@game_board["13"]} | 1"
    puts "=" * 13
    puts "| #{@game_board["21"]} | #{@game_board["22"]} | #{@game_board["23"]} | 2" 
    puts "=" * 13
    puts "| #{@game_board["31"]} | #{@game_board["32"]} | #{@game_board["33"]} | 3" #!!! "32" was inverted "23"
    puts "  1   2   3"
  end

  #---------->>>>>

  def finding_patterns
    temp_array = @senarios.map {|element| element == 'X' || element == 'O' ? element : " "}
    new_array = temp_array.each_slice(3)
    times = 0
    while times < 12
      poss_match = new_array.next.join
      @master_hash.each do |key, value|
        if key == poss_match
          return value,times
        end
      end
      times =+ 1                                     #!!! this was in the wrong place and messed up the pattern finding
    end                                              #!!! iterating through @scenarios and @master_hash, it might be better 
  end                                                #!!! to give the index counter a name that reflects this

  #---------->>>>>

  def game_winner?
    value, times = finding_patterns                      #!!! must assign the return values (was missing)
    if value == 'winner_X' || value[0] == 'winner_O'     #!!! should allow for X or O to win
      value                                              #!!! return winner    
    else
      nil
    end
  end

  
  #---------->>>>>

#  if $0 == __FILE__                                 
#    print "\n\nYou are X.  Please go first."        #!!! if you have classes in different files, this sort of auto launch code
#    TicTacToeGame.new.game_play                     #!!! will get you into trouble.
#  end
end

#!!! class ends here
#---------->>>>>

print "\n\nYou are X.  Please go first."
TicTacToeGame.new.game_play

This post has been edited by modi123_1: 23 September 2013 - 05:59 PM
Reason for edit:: please use code tags

Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2102
  • View blog
  • Posts: 3,208
  • Joined: 21-June 11

Re: Tic Tac Toe Game Code help

Posted 24 September 2013 - 04:42 AM

And what are the error messages you're getting?

By the way: Who wrote your comments (by the way they're phrased I'm assuming it wasn't you)? And is that person saying that you shouldn't do if $0 == __FILE__, but rather do what you're doing now? Because I'd recommend the opposite (i.e. uncomment lines 231 to 235 and remove lines 340 and 341 - though you should probably move lines 231 to 235 outside of the class definition).

Also you should probably remove the comments once you've understood them because they don't really help the understandability of the code. If you want to keep a log of changes done to the code, you should use commit messages for that, not comments.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1