0

我正在用 Ruby 实现五子棋游戏,这是在 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

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

4

1 回答 1

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]两次开始计算一个。但是有些对角线太短了,所以我们只想取从前 11 行和列开始的那些(因为其他的会短于 5 个元素)。这就是前三行的作用:[i, j]will be [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]; 我们在列表中的这些坐标处收集值。同时,我们还将处理左下对角线;那是 othermap的工作,它翻转一个坐标。因此,内部块将返回一个二元素数组,它是两个对角线,一个在左下,一个在右下。flat_map将在压缩二元素数组时进行迭代,以便我们得到一个大的对角线数组,而不是二元素对角线数组的数组。

于 2014-09-08T07:29:59.870 回答