假设结果在纸上看起来像这样:
x o o
x o x
o x o
你想知道是否有赢家,如果有,谁赢了。该图可以由数组表示:
toe = [[:x, :o, :o], [:x, :o, :x], [:o, :x, :o]]
(我可以使用字符串'x'
and 'o'
,但是使用符号更有效并且可以节省击键次数。我也可以使用0
and1
或true
and false
,但这样做没有任何优势。)
让我们定义一个方法,:x
如果x
获胜,:o
如果o
获胜或:no_winner
没有获胜者则返回:
def winner?(toe)
return :x if player_wins?(toe, :x)
return :o if player_wins?(toe, :o)
:no_winner
end
whereplayer_wins?(toe, p)
是返回true
or的方法false
,取决于玩家p
( :x
or :o
) 是否获胜。要编写该方法,我们可以使用以下辅助方法(您可以单独测试)。
player 的任何行赢家p
?
def row_win?(toe, p)
toe.any? { |row| row.uniq == p }
end
主对角线是玩家的赢家p
吗?
def diag_win?(toe, p)
3.times.all? { |i| toe[i][i] == p }
end
非对角线是玩家的赢家p
吗?
def off_diag_win?(toe, p)
3.times.all? { |i| toe[2-i][i] == p }
end
使用这些助手,我们可以编写player_wins?
如下:
def player_wins?(toe, p)
row_win?(toe, p) ||
row_win?(toe.transpose, p) ||
diag_win?(toe, p) ||
off_diag_win?(toe, p)
end
让我们尝试一下:
winner?(toe)
#=> :o
另一个例子:
winner? [[:x, :o, :o], [:o, :o, :x], [:x, :x, :o]]
#=> :no_winner