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

Time:11-28

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
  • Related