How to use an array method as condition for if statement in Ruby

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.


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.

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)
  :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

game = [[:X, :O, :X],
        [:O, :X, :O], 
        [:O, :X, :X]]
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