思考这个问题的最佳方式是一个人的想法。没有人会对自己说“a and b and c, or if d and e and f”等等。他们会说“任意三个连续,水平、垂直或对角线。”
另外,您可以只进行四次检查(三行和一条对角线),而不是进行八次检查(3 行、3 列和 2 条对角线),然后将棋盘旋转 90 度,然后再次进行相同的检查。
这就是你最终的结果。这些函数都假设棋盘是一个 3×3 的布尔矩阵,其中 true 代表中奖符号,false 代表未中奖符号。
def win?(board)
winning_row_or_diagonal?(board) ||
winning_row_or_diagonal?(rotate_90(board))
end
def winning_row_or_diagonal?(board)
winning_row?(board) || winning_diagonal?(board)
end
def winning_row?(board)
3.times.any? do |row_number|
three_in_a_row?(board, row_number, 0, 1, 0)
end
end
def winning_diagonal?(board)
three_in_a_row?(board, 0, 0, 1, 1)
end
def three_in_a_row?(board, x, y, delta_x, delta_y)
3.times.all? do |i|
board[x + i * delta_x][y + i * deltay]
end
end
def rotate_90(board)
board.transpose.map(&:reverse)
end
矩阵旋转来自这里:https://stackoverflow.com/a/3571501/238886
虽然这段代码有点冗长,但每个函数的意图都很明确。代码现在表达的是井字游戏规则,而不是长布尔表达式。