4

So I am building a tic tac toe game and I am trying to pull keys from my board hash and then compare that with arrays within an array. The issue is that the winning combos all have 3 values, but it may take a player 4 or 5 moves to win, so I want to see if those 4 or 5 values include one of the winning combos (hopefully that makes sense). Specifically the issue is with the winner_check method, is there a way to get this method working?

def initialize_board
  board = {}
  (1..9).each {|position| board[position] = ' ' }
  board
end

def empty_positions(board)
  board.keys.select {|position| board[position] != 'X' && 'O'}
end

def player_turn(board)
  puts "Let's play Tic Tac Toe! Pick a position 1-9 and try to beat me."
  position = gets.chomp.to_i
  board[position] = 'X'
end

def computer_turn(board)
  position = empty_positions(board).sample
  board[position] = 'O'
end

def winner_check(board)
  winning_combos = [[1, 2, 3], 
    [4, 5, 6], 
    [7, 8, 9], 
    [1, 4, 7], 
    [2, 5, 8], 
    [3, 6, 9], 
    [1, 5, 9],
    [3, 5, 7]]
    winning_combos.each {|combo|}
      if board.select { |k,v| v == 'X' }.keys.include?(combo)
        puts "You've won! Great job!"
      if board.select { |k,v| v == 'O' }.keys.include?(combo)
        puts "Looks like the computer outsmarted you, try again!"
      elsif
        puts "Looks like you've tied, try again!"
      end
    nil
  nil
end

def game_over?(board)
  empty_positions(board) == []
end

def draw_board(board)
  puts
  puts " #{board[1]} | #{board[2]} | #{board[3]} "
  puts "---+---+---"
  puts " #{board[4]} | #{board[5]} | #{board[6]} "
  puts "---+---+---"
  puts " #{board[7]} | #{board[8]} | #{board[9]} "
  puts
end

board = initialize_board
draw_board(board)

until winner_check(board) || game_over?(board)
  player_turn(board)
  draw_board(board)
  winner_check(board)
  computer_turn(board)
  draw_board(board)
  winner_check(board)
end
4
  • +1 Welcome to SO, and to Ruby! Commented Nov 3, 2014 at 22:35
  • 2
    What is the error you are getting? What happens when you run the program, Please post the output. Thanks Commented Nov 3, 2014 at 22:42
  • It's great to see a newbie post such a clear question! Regarding the error, error messages need to be studied carefully, as they often contain valuable information for debugging. When you post a question that describes a situation where an exception was raised, be sure to show both the (possibly trimmed) error message and the line on which it occurred. Commented Nov 3, 2014 at 23:17
  • Your code will be easier to read, debug and maintain if you avoid replication as much as possible. Here, for example, you might define a one-line helper method win?: def win?(combos, board, ch); combos.any? { |positions| positions.all? { |pos| board[pos-1] == ch } }; end, allowing you to write if win?(combos, board, 'X'); puts "You've won.."; elsif win?(combos, board, 'O'); puts.... You can now easily test that method to be sure it's working and I think it reads better too. Note I employed the Enumerable methods, any? and all?, which is more Rubyish. Commented Nov 3, 2014 at 23:43

1 Answer 1

1

I think you're on the right track, but you have some syntax errors:

winning_combos.each {|combo|}
  if board.select { |k,v| v == 'X' }.keys.include?(combo)
    puts "You've won! Great job!"
  if board.select { |k,v| v == 'O' }.keys.include?(combo)
    puts "Looks like the computer outsmarted you, try again!"
  elsif
    puts "Looks like you've tied, try again!"
  end
nil

On the first line, you close your block too early. The } at the end of the line closes the block.

On the last line, where you have a literal nil, I think that's where your closing } should go.

You also have two ifs in a row, should be if, elsif.

Syntax errors corrected:

winning_combos.each { |combo|

  if board.select { |k,v| v == 'X' }.keys.include?(combo)
    puts "You've won! Great job!"
  elsif board.select { |k,v| v == 'O' }.keys.include?(combo)
    puts "Looks like the computer outsmarted you, try again!"
  elsif
    puts "Looks like you've tied, try again!"
  end
}
Sign up to request clarification or add additional context in comments.

4 Comments

You should show a fixed/correct sample, not just describe it. Remember, a picture is worth 1,000 words.
Thank you so much Jared! I have fixed some of my syntax errors, but still when I run this file, I get the following error: syntax error, unexpected end-of-input, expecting keyword_end This is what my code looks like now:
def winner_check(board) winning_combos = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 5, 9], [3, 5, 7]] winning_combos.each do |combo| if board.select { |k,v| v == 'X' }.keys.include?(combo) puts "You've won! Great job!" if board.select { |k,v| v == 'O' }.keys.include?(combo) puts "Looks like the computer outsmarted you, try again!" elsif puts "Looks like you've tied, try again!" end end nil end
Jessica, you have if board...if board...elsif. That needs to be if board...elsif board...elsif

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.