写一个&&的列表的更好方法检查?

时间:2013-11-15 14:40:28

标签: ruby

我正在努力寻找更好的方法来编写这段代码:

def down_up(array, player)
    7.downto(3).each do |row|
      8.times do |column|
        if array[row][column] == player
          if array[row - 1][column] == player && array[row - 2][column] == player && array[row - 3][column] == player
            return :winner
          end   
        end  
      end   
    end
    return :nothing_yet
  end

特别是这一行:

if array[row - 1][column] == player && array[row - 2][column] == player && array[row - 3][column] == player

如果一个单元格匹配,则检查3个连续的行是否也匹配 - 但是有很多冗余。重构&&条件列表的一般方法是什么?

4 个答案:

答案 0 :(得分:11)

写如下:

 if [1,2,3].all?{|i| array[row - i][column] == player }

答案 1 :(得分:3)

如果这些行重复很多,你可能想制作方法:

def consecutive_rows(array, row, column)
   array[row - 1][column] == player && array[row - 2][column] == player && array[row - 3][column] == player
end

并在您的代码中:

return :winner if consecutive_rows(array, row, column)

答案 2 :(得分:1)

您的代码显然不优雅的一点是,您要分离array[row]条件和array[row - 1]array[row - 2]array[row - 3]条件。它们应该作为array[row - 3, 4]的条件放在一起。

def down_up(array, player)
  (3..7).any?{|i| (0..7).any?{|j| array[i - 3, 4].all?{|a| a[j] == player}}} ?
  :winner : :nothing_yet
end

答案 3 :(得分:1)

作为替代方案,您可能需要重新排列方法:

def down_up(array, player)
  rows    = 7.downto(3).to_a
  columns = 7.downto(0).to_a

  rows.product(columns).detect(-> { :nothing_yet }) do |row, column|
    next unless array[row][column] == player

    if [1,2,3].all?{|i| array[row - i][column] == player }
      :winner
    end
  end
end