I'm creating a tic tac toe game in the command line using Ruby. I have a method display_board that displays my array as a game board in the command line and when I play the game players can choose between 1-9 and populate the square with their "symbol". I created a method check_square to verify if one of the squares in the grid has already been taken but it's not working properly for me. I start up the game and everything works, up until it asks me to choose my first number on the grid. It immediately responds and tells me the number is already taken even though it's the first move of the game. It asks me to choose another number and on the second try it populates the grid. It does this on every player move. The logic seems to make sense to me and I've been trying to figure it out for an hour but I'm clearly overlooking something. Any pushes in the right direction would be helpful!
class Players
attr_accessor :name, :symbol
def initialize(name, symbol)
@name = name
@symbol = symbol
end
end
class Game
@@board = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
@@count = 0
def initialize
puts "Tic Tac Toe!"
end
def display_board
puts " #{@@board[0]} | #{@@board[1]} | #{@@board[2]}"
puts seperator = "-----+-----+-----"
puts " #{@@board[3]} | #{@@board[4]} | #{@@board[5]}"
puts seperator
puts " #{@@board[6]} | #{@@board[7]} | #{@@board[8]}"
puts "\n"
end
def game_start
puts "Time for some Tic Tac Toe! Enter your name player 1: \n"
player1 = gets.chomp
puts "Would you like to be X or O #{player1}?"
symbol1 = gets.chomp.upcase
player_one = Players.new(player1, symbol1)
puts "And a name for player 2: \n"
player2 = gets.chomp
symbol2 = player_one.symbol == "X" ? "O" : "X"
player_two = Players.new(player2, symbol2)
puts "\n"
puts "Okay #{player_one.name}, you're up. Make a move."
display_board
make_moves(player_one, player_two)
end
def make_moves(player_one, player_two)
until @@count == 9
puts "Pick a number from the grid above #{player_one.name}"
move = gets.chomp.to_i - 1
check_square(move, player_one, player_two)
@@board[move] = player_one.symbol
@@count += 1
display_board
puts "Pick a number from the grid above #{player_two.name}"
move = gets.chomp.to_i - 1
check_square(move, player_one, player_two)
@@board[move] = player_two.symbol
@@count += 1
display_board
end
end
def check_square(move, player_one, player_two)
if @@board[move] == "#{player_one.symbol}" || "#{player_two.symbol}"
puts "That number is taken, pick another!"
move = gets.chomp.to_i - 1
else
return
end
end
end
game = Game.new
game.game_start
The problem you're running into is the conditional logic in your check_square
method.
@@board[move] == "#{player_one.symbol}" || "#{player_two.symbol}"
This logic is suppose to check if either of the players' symbols is stored on the board at the selected position. However, what it is really doing is checking if player one's symbol is stored on the board at that position and if it's not then the string literal for player two's symbol is being evaluated as truthy. This results in check_square
always returning true
Try this instead:
@@board[move] == "#{player_one.symbol}" || @@board[move] == "#{player_two.symbol}"
For more idiomatic ruby you can remove the interpolation which isn't necessary since symbol is already a string.
@@board[move] == player_one.symbol || @@board[move] == player_two.symbol