我正在努力寻找一种计算正方形对角线的 64 位表示的有效方法。
有问题的游戏是一款名为 Othello 或 Reversi 的棋盘游戏。我目前正在研究一种确定作品稳定性的方法。稳定的棋子可以定义为不能翻转的棋子。我正在处理的当前问题可以定义为:“如果所有四个方向的所有方格都被占用,则无法翻转一块。”
因此,例如,如果棋盘如下所示,则无法捕获标有 A 的棋子:
/* 1 2 3 4 5 6 7 8
* 1 . . x . . . x .
* 2 . . x . . x . .
* 3 x . x . x . . .
* 4 . x x x . . . .
* 5 x x A x x x x x
* 6 . x x x . . . .
* 7 x . x . x . . .
* 8 . . x . . x . .
*/
其中 x 表示该位置存在一块(无论其颜色如何)。由于该棋子被各个方向的棋子包围,因此无法捕获。
垂直线很容易计算。在一个 8x8 的嵌套 for 循环中,可以通过 ver0 >> j 找到下一条垂直线,而通过 hor0 >> i*8 可以找到下一条水平线。
const unsigned long long hor0 = 255ULL;
const unsigned long long ver0 = 72340172838076673ULL;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
currHor = hor0 << i;
currVer = ver0 << j;
}
}
作为一个视觉示例,hor0 看起来像:
/* 1 2 3 4 5 6 7 8
* 1 x x x x x x x x
* 2 . . . . . . . .
* 3 . . . . . . . .
* 4 . . . . . . . .
* 5 . . . . . . . .
* 6 . . . . . . . .
* 7 . . . . . . . .
* 8 . . . . . . . .
*/
因此移位 8 会将线下移 1。
ver0 看起来像:
/* 1 2 3 4 5 6 7 8
* 1 x . . . . . . .
* 2 x . . . . . . .
* 3 x . . . . . . .
* 4 x . . . . . . .
* 5 x . . . . . . .
* 6 x . . . . . . .
* 7 x . . . . . . .
* 8 x . . . . . . .
*/
因此,移位一位会将线向右移动一位。
要找到他们的组合光标,我只需 OR 结果:
currCursor = (currHor | currVer);
现在真正的问题开始了。为了确定稳定性,我需要所有四个方向。我不确定如何仅使用 (i, j) 位置可行地计算对角线。
我的第一次尝试是使用位移。这非常失败,因为当我不想要垃圾位时,移位会导致镜像。
我的第二次尝试是简单地将所有对角线放在一个数组中,并使用索引来查找相应的线。该数组非常大,但这里是一些元素外观的示例(仅左对角线):
const unsigned long long rightDiagonals[15] = { \
9241421688590303745ULL, \
/* 1 2 3 4 5 6 7 8
* 1 x . . . . . . .
* 2 . x . . . . . .
* 3 . . x . . . . .
* 4 . . . x . . . .
* 5 . . . . x . . .
* 6 . . . . . x . .
* 7 . . . . . . x .
* 8 . . . . . . . x
* [0] //This is the index in the array.
*/
36099303471055874ULL, \
/* 1 2 3 4 5 6 7 8
* 1 . x . . . . . .
* 2 . . x . . . . .
* 3 . . . x . . . .
* 4 . . . . x . . .
* 5 . . . . . x . .
* 6 . . . . . . x .
* 7 . . . . . . . x
* 8 . . . . . . . .
* [1]
*/
...
144396663052566528ULL, \
/* 1 2 3 4 5 6 7 8
* 1 . . . . . . . .
* 2 . . . . . . . .
* 3 . . . . . . . .
* 4 . . . . . . . .
* 5 . . . . . . . .
* 6 . . . . . . . .
* 7 x . . . . . . .
* 8 . x . . . . . .
* [13]
*/
72057594037927936ULL}
/* 1 2 3 4 5 6 7 8
* 1 . . . . . . . .
* 2 . . . . . . . .
* 3 . . . . . . . .
* 4 . . . . . . . .
* 5 . . . . . . . .
* 6 . . . . . . . .
* 7 . . . . . . . .
* 8 x . . . . . . .
* [14]
*/
我不知道如何将数组的索引与 (i, j) 索引匹配。例如,如果一个正方形在索引 (2, 1) 上,则对应的索引应该是数组中的 [1]。但是如果正方形在 (3, 2) 上,则数组的索引也应该是 [1]。如果正方形在 (1,1), ... (7, 7), (8, 8) 上,则索引应为 [0]。
我无法确定一种轻松找到线路的方法。我想到的一件事是获取当前正方形的 64 位表示形式,然后将其与两条线的交点进行或运算。问题是这将需要一个 for 循环,并且此操作将执行数千次,这在计算上不是最优的。
有人知道从单个正方形计算对角线的方法或计算对角线数组中相应索引的方法吗?
非常感谢您的帮助。