2

我正在构建一个播放 Connect 4 的程序,要检查的一件事是你的对手有以下棋盘位置的情况:

[0,1,1,0,0] 或 [0,1,0,1,0] 或 [0,0,1,1,0]

你的对手距离连续三张棋子只有一步之遥,两边都是空白。如果您在下一步行动中没有填充中间元素之一,您的对手可以去那里并迫使将死。

我有一个 42 个方格的棋盘,编号为 1:42。我创建了一个名为 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)];

是棋盘的两条对角线。

我可以测试可能的将死

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

这给了我一个带有 1 的向量,表示相应的 FiveCheck 行有一个可能的将死。假设该向量的第 34 个元素具有 1,并且该对角线的模式(来自上面给出的示例)是 [0,0,1,1,0]。我如何返回 14,我应该移动到的棋盘位置?

另一个单独的示例,如果该向量的第 35 个元素为 1,并且该对角线的模式是 [0,1,0,1,0],我如何返回 28?

编辑:我刚刚意识到,如果没有某种地图,这是不可能的。所以我创建了 FiveMap,一个与 FiveCheck 大小相同的矩阵,除了删除了单词“board”之外,使用相同的公式。例如:

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

1 回答 1

1

由于您正在处理大小为 5 的二进制向量,因此一个非常有效的解决方案可能是使用查找表。

考虑board为二进制矩阵。您可以使用 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 回答