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 が与えたのと同じテストを適用できます。

編集:これは何をしますか

対角線を見ると、左下がりと右下がりの2種類があります。今のところ、右下のものに焦点を当てましょう。15x15 の行列には、29 個の右下の対角線があります。最初の行の各要素から始まるものと、最初の列の各要素から始まるものがありますが、[0, 0]2 から始まるものをカウントしないように注意してください。ただし、一部の対角線は短すぎるため、最初の 11 行と 11 列から始まるもののみを取得します (他のものは 5 要素より短いため)。これが最初の 3 行の動作です: [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]: dis5[10, 0]、だから私たちは、、、、、を持って[11, 1][12, 2]ます。リスト内のそれらの座標で値を収集します。同時に、左下の対角線にも取り組みます。それは、一方の座標を反転させるもう一方の仕事です。したがって、内側のブロックは 2 つの要素の配列を返します。これは 2 つの対角線で、1 つは左下、もう 1 つは右下です。対角線の 2 要素配列の配列ではなく、対角線の 1 つの大きな配列を取得するように、2 要素配列を圧縮しながら反復処理を行います。[13, 3][14, 4]mapflat_map

于 2014-09-08T07:29:59.870 に答える