gpt4 book ai didi

c++ - 在使用位板的国际象棋引擎中,如何检测边缘?

转载 作者:行者123 更新时间:2023-12-02 16:12:12 24 4
gpt4 key购买 nike

例如,所有白兵的攻击都是通过向左移动 7 位或 9 位(或向右移动,我可能错了,但我认为这很容易理解要点)生成。

所以看起来像这样的白色棋子位板

00000000000000000000000000000000000000001111111100000000

将转移到这里

00000000000000000000000000000001111111100000000000000000

但是,如果您尝试在 8x8 阵列中描绘此示例,其中一个棋子会穿过棋盘的边缘。

那么,当移动位以生成攻击时,引擎如何防止自己生成穿过棋盘边缘的攻击?

最佳答案

我们将添加一些空格。假设你从一个棋子位置开始:

00000000
00000000
00000000
00000000
00000000
10000000
01100101
00011010
00000000
00000000

换行只是为了便于阅读,一切都是打包的位。棋子可以移动到哪里?

00000000
00000000
00000000
00000000
10000000
01100101
00011010
00000000
00000000
00000000

在这里,越过边缘的唯一风险是在顶部,这很容易处理。

接下来,棋子可以拿去哪里呢?天真的解决方案是采用上面的“移动”掩码,并将其左右移动 1。如您所见,这会导致环绕。

00000000
00000000
00000000
00000001
00000000
11001010
00110100
00000000
00000000
00000000
|
00000000
00000000
00000000
00000000
01000000
00110010
10001101
00000000
00000000
00000000

(如果您不喜欢我选择的字节顺序,我深表歉意)。

我们可以通过一些掩蔽来解决这个问题。将环绕的位位于已知位置。所以我们在进行操作之前将它们屏蔽掉。

这个面具:

11111110
11111110
11111110
11111110
11111110
11111110
11111110
11111110

在我们向右移动之前,以及

01111111
01111111
01111111
01111111
01111111
01111111
01111111
01111111

在我们向左移动之前。

因此,要查看受兵威胁的地点,其中“前进”是右移,我们这样做:

auto pawn_moves = pawn_mask >> 8;
auto pawn_left_take = (pawn_moves & not_left_column) << 1;
auto pawn_right_take = (pawn_moves & not_right_column) << 1;
auto pawn_take = pawn_left_take | pawn_right_take;

就这样。

可以对其他情况进行类似的屏蔽。例如,如果我们正在计算骑士拿面具,我们需要 8 个面具和 8 个类次,然后将它们放在一起。

对于向右移动 3 的车,您屏蔽掉右边的 3 列,然后在车 mask 上进行右 3 移动。

然而,在某些时候,您可能想要使用内部函数和 SIMD 处理;因此,您所拥有的准确的位操作将取决于您的硬件。也许将 8 个 8 位值解包为 8 个 24 位值,在那里进行无掩码操作,然后提取中间 8 位是您特定硬件上最快的方法。

关于c++ - 在使用位板的国际象棋引擎中,如何检测边缘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67680354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com