2

私は Connect 4 をプレイするプログラムを構築しています。チェックすべきことの 1 つは、対戦相手が次のボード ポジションを持っている場合です。

[0,1,1,0,0] または [0,1,0,1,0] または [0,0,1,1,0]

対戦相手は、両側に空白のある 3 つのピースが並んでいる状態から 1 手離れています。次の手で真ん中の要素の 1 つを満たさない場合、対戦相手はそこに行き、チェックメイトを強制することができます。

私が持っているのは、1:42 の番号が付けられた 42 個の正方形のボードです。そして、各行が 5 つの連続するボード位置に対応する FiveCheck というマトリックスを作成しました。例えば:

    FiveCheck(34,:) = [board(7),board(14),board(21),board(28),board(35)];
    FiveCheck(35,:) = [board(14),board(21),board(28),board(35),board(42)];

ボードの対角線の 2 つです。

チェックメイトの可能性をテストできます

    (sum(FiveCheck(:,2:4),2) == 2 + sum(FiveCheck,2) == 2) == 2

これにより、対応する FiveCheck 行にチェックメイトの可能性があることを示す 1 を持つベクトルが得られます。そのベクトルの 34 番目の要素が 1 で、その対角線のパターン (上記の例から) が [0,0,1,1,0] であるとします。移動すべきボードの位置である 14 を戻すにはどうすればよいですか?

別の別の例として、そのベクトルの 35 番目の要素が 1 で、その対角線のパターンが [0,1,0,1,0] の場合、どうすれば 28 を返すことができますか?

編集: ある種の地図がなければ、これは不可能であることに気付きました。そこで、FiveCheck と同じサイズの行列である FiveMap を作成しましたが、"board" という単語が削除されていることを除いて、同じ数式が使用されています。例えば:

    FiveMap(34,:) = [(7),(14),(21),(28),(35)];
    FiveMap(35,:) = [(14),(21),(28),(35),(42)];
4

1 に答える 1

1

サイズ5のバイナリベクトルを扱っているので、非常に効率的な解決策はルックアップテーブルの使用かもしれません。

boardバイナリ行列であると考えてください。水平、垂直、および2つの対角線を表す、4つのフィルター(長さ5)でフィルター処理して、探している可能性のある位置を特定できます。次に、特定の場所について、5つのバイナリビットを抽出し、サイズ32のルックアップテーブルを使用して、ピースを配置する位置へのオフセットを取得できます。

小さな例:

% construct LUT
LUT = zeros(32,2); % dx and dy offsets for each entry
LUT(12,:) = [ 1 0 ]; % covering the case [0 1 1 0 0] - put piece 1 to the right of center
% continue constructing LUT here...

horFilt = ones(1, 5);
resp = imfilter( board, horFilt ); % need to think about board''s boundaries here...
[yy xx] = find( resp == 2 ); all locations where filter caught 2 out of 5
pat = board( yy, xx + [ -2 1 0 1 2] ); % I assume here only one location was found
pat = bin2dec( '0'+char( pat ) ); % convert binary pattern to decimal entry
board( yy + LUT(pat,2) , xx + LUT(pat, 1) ) = ... ; % your move here...
于 2012-12-15T20:52:38.940 に答える