我正在Ruby中实现gomoku游戏,这是在15x15板上玩的井字游戏的变体,第一个在水平,垂直或对角线上放置5个O或X的玩家获胜。
首先,我将Matrix分配给一个变量并用0到224之间的数字填充它,所以没有重复,我可以在以后计算它们
gomoku = Matrix.zero(15)
num = 0
15.times do |i|
15.times do |j|
gomoku[i, j] = num
num += 1
end
end
然后玩家轮流,每次转弯后我用方法win?
def win? matrix
15.times do |i|
return true if matrix.row_vectors[i].chunk{|e| e}.map{|_, v| v.length}.max > 4 # thanks to sawa for this way of counting adjacent duplicates
return true if matrix.column_vectors[i].chunk{|e| e}.map{|_, v| v.length}.max > 4
end
return false
end
我知道,我可能做错了,但我的问题不是这样,尽管欢迎提出建议。问题在于对角行。我不知道如何计算对角行中的重复项
答案 0 :(得分:1)
diagonal_vectors = (-10 .. 10).flat_map do |x|
i = x < 0 ? 0 : x
j = x < 0 ? -x : 0
d = 15 - x.abs
[
d.times.map { |k|
gomoku[i + k, j + k]
},
d.times.map { |k|
gomoku[i + k, 14 - j - k]
}
]
end
有了这个,你可以应用sawa给你的相同测试。
编辑:这是做什么
在观察对角线时,有两种:左下和下右。让我们现在专注于右下角。在15x15矩阵中,有29个右下对角线:一个从第一行的每个元素开始,一个从第一列的每个元素开始,但注意不要计算从[0, 0]
开始的两次。但是一些对角线太短,所以我们只想采取那些从前十一行和第一列开始的对角线(因为其他对角线将短于5个元素)。这就是前三行:[i, j]
将是[10, 0]
,[9, 0]
...... [0, 0]
,[0, 1]
,... [0, 10]
。 d
是从该位置开始的对角线的长度。然后,d.times.map { |k| gomoku[i + k, j + k] }
收集该对角线中的所有元素。假设我们正在处理[10, 0]
:d
为5
,因此我们有[10, 0]
,[11, 1]
,[12, 2]
,[13, 3]
,[14, 4]
;我们在列表中的那些坐标处收集值。同时,我们也将在左下对角线上工作;这是另一个map
的工作,它会翻转一个坐标。因此,内部块将返回两个元素阵列,即两个对角线,一个左下,一个右下。 flat_map
将负责迭代,同时压缩双元素数组,以便我们得到一个大的对角线数组,而不是对角线的双元素数组。