如何检查线上的点?

时间:2015-10-16 18:15:30

标签: ruby cartesian-coordinates

我试图在红宝石中实现free monad游戏。我有笛卡尔坐标(0

Result

上表中包含x|x|x - - - x|x|x - - - x|x|x 的地方是我可以放置xx标志的地方。如何检查一些标志的集合是否组成一条直线?

1 个答案:

答案 0 :(得分:0)

假设结果在纸上看起来像这样:

x o o
x o x
o x o

你想知道是否有赢家,如果有,谁赢了。该图可以用数组表示:

toe = [[:x, :o, :o], [:x, :o, :x], [:o, :x, :o]]

(我本可以使用字符串'x''o',但使用符号会更有效并节省按键次数。我也可以使用01或{{ 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的方法,具体取决于玩家falsep: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