我试图在红宝石中实现free monad游戏。我有笛卡尔坐标(0 上表中包含Result
x|x|x
- - -
x|x|x
- - -
x|x|x
的地方是我可以放置x
或x
标志的地方。如何检查一些标志的集合是否组成一条直线?
答案 0 :(得分:0)
假设结果在纸上看起来像这样:
x o o
x o x
o x o
你想知道是否有赢家,如果有,谁赢了。该图可以用数组表示:
toe = [[:x, :o, :o], [:x, :o, :x], [:o, :x, :o]]
(我本可以使用字符串'x'
和'o'
,但使用符号会更有效并节省按键次数。我也可以使用0
和1
或{{ 1}}和true
,但这样做没有任何好处。)
让我们定义一个方法,如果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
是返回player_wins?(toe, p)
或true
的方法,具体取决于玩家false
(p
或:x
)是否获胜。要编写该方法,我们可以使用以下辅助方法(您可以单独测试)。
播放器:o
是否有任何获胜者?
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