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

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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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