【问题标题】:Generating individual moves from a bitboard of moves从移动位板生成单个移动
【发布时间】:2015-07-11 17:30:30
【问题描述】:
在我的国际象棋引擎中,它使用位板来表示棋盘的状态,一次生成一大块伪合法的移动,结果就是一个位板。例如:
棋子:
稍后会有一点位板魔术:
最后的位板只是一大块可能的动作。引擎通常如何利用这个位板并从中生成单独的移动?我是否必须遍历每一位以检查它是否已设置?不过,在位板上进行迭代似乎违背了使用位板的目的,这就是为什么我有点怀疑。
有没有更好的办法?
【问题讨论】:
标签:
bit-manipulation
chess
bitboard
【解决方案1】:
然后,您通常会应用minimax 算法的一些变体来评估这些动作的好坏,这样您就可以选择(您估计的)最佳动作。例如,一个简单的变体是alpha-beta。
这些变体主要处理尝试将搜索引导到“可能有用的移动”并远离搜索空间的无用区域,因为搜索树非常宽,并且您深入探索它的能力对于一盘好的国际象棋极为重要AI - 对它进行浅层探索会使 AI 很容易“陷入困境”,因为它会做出短期内看起来不错的选择,即使后来效果不佳。
所以是的,您将遍历位板。这并没有真正违背他们的目的——你仍然(可能)比不使用位板更快地计算移动。对于最简单的人工智能,你可以使用标准的位板技术采取“第一步”,但这样玩的人工智能将低于新手水平,根本不考虑输赢。
【解决方案2】:
您不必迭代超过 64 个单个位。例如,您可以准备/预定义一个 256 大小的查找数组,其中包含所有可能的移动列表,其中 8 位索引表示单个等级上的一块攻击集。然后,您可以使用按位移位操作 (bitboard >> 8) 仅迭代 8 次,以将后续的 rank-attack-sets 作为索引传递给数组并提取移动列表。与一位步进循环相比,它将加速大约 8 倍。也许您应该将此数组增强为 [8][256] 实际上也传递一个等级号本身并根据您的需要提取最终的移动列表(带有 x,y 坐标)。内存成本仍然微不足道。