为位板获得占用位掩码

时间:2011-06-24 06:11:37

标签: artificial-intelligence bit-manipulation chess

我正在使用位板代表棋盘并检查合法动作。我坚持的事情是计算滑动件攻击中源和目标方块之间的占用率。 我不想通过查找来做,所以我想弄清楚是否有可能在之间找到正方形的掩码而没有查找。例如,在下面的板中,c4上有一个Rook:


8 0 0 0 0 0 0 0 0 
7 0 0 0 0 0 0 0 0 
6 0 0 0 0 0 0 0 0 
5 0 0 0 0 0 0 0 0 
4 0 0 R 0 0 0 0 0 
3 0 0 0 0 0 0 0 0 
2 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 
  a b c d e f g h

给定一个代表空方块(或占用方块,更容易)的位板和伪有效移动Rf4(白嘴鸦可以从c4移动到f4),如何获得方块d4-e4的掩码(不包括源和目的地广场)?

我认为,一旦明确,垂直移动将很容易,并且可以使用旋转位板计算对角线移动。

编辑:位板用ulong / unsigned int64表示,每包8位代表实际电路板的等级/行。

3 个答案:

答案 0 :(得分:3)

我将在这里做一些假设:电路板存储为64位数字,每个8字节块代表一行。行中的每个位代表一列(a..h)。您有起始和终止位置作为从零开始的坐标。即: start = "C4" = [2,3]; end = "F4" = [5,3]

对于列数增加的水平移动,您可以计算移动的距离: d = (F4-C4 = 3) 。减去1以排除目的地,然后d-1位的“踪迹”t是 t = (1<<(d-1))-1 。移动与源片相邻的轨迹以获得蒙版M: M = t<<(start.row*8 + start.column+1)

这相当于      M = ((1<<d)-2)<<(start.row*8 + start.column)

另一种方式是水平移动:

 d = (C4-F4 = -3)
 t = (1<<(-d-1))-1
 M = (t<<dest.column+1)
 //-or-
 M = ((1<<-d)-2)<<(dest.row*8 + dest.column)

垂直增加动作:

 d = (C7-C4 = 3)
 t=(1<<8)
 (d-1) times: { t |= (t<<8)}
 M = t << (start.row*8 + start.column)

垂直减少移动:

 d = (C4-C7 = 3)
 t=(1<<8)
 (d-1) times: { t |= (t<<8)}
 M = t << (dest.row*8 + start.column)

对于垂直移动,您可以通过存储最大“垂直轨迹”VT = 0x0101010101010101 = 72340172838076673来替换d上的循环。然后为实际移动掩盖正确的位数。

这会减少对M = (VT & ((1<<(d*8)) - 2)) << (row*8+column)的影响。

你可能会为对角线移动做类似的事情。从最大对角线路径DT = 0x0102040810204080开始,应用掩码将其减少到d设置位,并切换到开始或结束位置,具体取决于哪个更接近边缘。这需要仔细测试,以确保没有边缘情况缠绕到错误的行。

已修改为排除源和目标,并修复一次性错误

答案 1 :(得分:1)

如果没有做一些前期计算并为片段移动生成所有可能的掩码(一定的可能性),我希望在运行时构建掩码很可能在时间上和简单的一样昂贵。查找每个方块的方法。

答案 2 :(得分:0)

获取方向(dx,dy)/ dx

的统一向量

在这种情况下,(1,0)

然后重复增加该矢量的当前位置,直到到达目的地。正在进行增量/分配相应的矩阵单元格。