I'm building a tic tac toe game in Ruby. To determine if someone has won the game, I have a 2d array, check_array, of all of the possible sets you could use to win. I want to see if any of those arrays in check array have all the same elements. My javascript brain is having a hard time figuring out how to do this in Ruby. I'm confused without my curlies to delineate the block. I understand this sort of syntax:
if check_array.any? {|row|row.uniq.count == 1}
@winner = @whos_turn
winning
end
But what if I need to use more than one line of logic for my any? logic. Could it look like this?
if check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
@winner = @whos_turn
winning
end
CodePudding user response:
Just use a separate variable.
match = check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
if match
@winner = @whos_turn
winning
end
or, even better,
def my_check(row)
row.uniq.count == 1
<<some more code>>
end
if check_array.any? { |x| my_check(x) }
@winner = @whos_turn
winning
end
I don't know if the proposed nested do .. end
syntax works, but the fact that I have no idea indicates to me that it's not very intuitive and should be refactored.
CodePudding user response:
No matter how you do it, you certainly don't have to worry about the code being efficient. I therefore suggest you focus on code that is readable and easy to test, perhaps something along the following lines.
Suppose:
game = [[:X, :O, :X],
[:O, :X, :O],
[:O, :X, :X]]
def winner(game)
return :X if player_win?(game, :X)
return :O if player_win?(game, :O)
return :NO_WINNER
end
def player_win?(game, mark)
row_win?(game, mark) || col_win?(game, mark) || diag_win?(game, mark)
end
def row_win?(game, mark)
game.any? { |row| row == [mark, mark, mark] }
end
def col_win?(game, mark)
row_win?(game.transpose, mark)
end
def diag_win?(game, mark)
3.times.all? { |i| game[i][i] == mark } ||
3.times.all? { |i| game[i,2-i] == mark }
end
For game
as defined above,
winner(game)
#=> :X
game = [[:X, :O, :X],
[:O, :O, :O],
[:X, :X, :_]]
winner(game)
#=> :O
game = [[:X, :O, :X],
[:O, :O, :X],
[:X, :X, :O]]
winner(game)
#=> :NO_WINNER