计算棋盘棋位图的占用位掩码

我正在使用棋位图来表示棋盘并检查合法的移动。我遇到的问题是计算滑动棋子攻击中起始格和目标格之间的占用情况。我不想通过查找表来解决,所以我正试图弄清楚是否有可能在不使用查找表的情况下获得中间格子的掩码。 例如,在下面的棋盘中,c4 上有一个车:

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 位代表棋盘的一行/列。


回答:

我在这里做一些假设:棋盘存储为一个 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) //-或- M = ((1<<-d)-2)<<(dest.row*8 + dest.column)

对于垂直递增的移动:

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

对于垂直递减的移动:

 d = (C4-C7 = 3) t=(1<<8) (d-1) 次: { 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 设置的位,并根据哪个更靠近边缘,将其移动到开始或结束位置。 这将需要仔细测试以确保没有边缘情况会环绕到错误的行中。

编辑以排除起始和目标位置,并修复一些一次性错误

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注