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