Ruby计算矩阵对角行中的重复数

时间:2014-09-08 06:47:38

标签: ruby matrix gomoku

我正在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

我知道,我可能做错了,但我的问题不是这样,尽管欢迎提出建议。问题在于对角行。我不知道如何计算对角行中的重复项

1 个答案:

答案 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]d5,因此我们有[10, 0][11, 1][12, 2][13, 3][14, 4];我们在列表中的那些坐标处收集值。同时,我们也将在左下对角线上工作;这是另一个map的工作,它会翻转一个坐标。因此,内部块将返回两个元素阵列,即两个对角线,一个左下,一个右下。 flat_map将负责迭代,同时压缩双元素数组,以便我们得到一个大的对角线数组,而不是对角线的双元素数组。