使用特定代码在二进制数组中查找行号

时间:2012-12-14 18:25:21

标签: matlab

我正在构建一个播放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)];

1 个答案:

答案 0 :(得分: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...