象棋编程:如何最有效地从位棋盘攻击掩码中获取单个走法

3

我如何高效地从攻击掩码中获取单个移动,它看起来像这样:

....1...
1...1...
.1..1..1
..1.1.1.
...111..
11111111
..1.11..
.1..1.1.

为一位女王。

在过去,我通过计算尾随零(bitScanForward)获取了女王的每一个可能移动的方格索引, 并在生成新的走法后,从攻击掩码中删除此方格,并继续下一个攻击方格。是否有直接获取单个攻击位的技术?

1个回答

1
我认为你描述的已经是最有效的方法了。循环遍历位棋盘,直到为零并一次选择一个移动。
用一些代码来概述这个想法,可能会像这样:
using Bitboard = uint64_t; // 64 bit unsigned integer

pMoves createAllMoves(Bitboard mask, int from_sq, Move* pMoves) {
  while(moves != 0) {
    int to_sq = findAndClearSetBit(mask);
   *pMoves++ = createMove(from_sq, to_sq);
  }
  return pMoves;
}

findAndClearSetBit 函数可以选择任何设置的位,但在当今的硬件上,找到最低有效位最有效。如果您使用的是GCC或Clang,您可以使用 __builtin_ctzll,它应该针对特定的硬件进行了优化:

int findAndClearSetBit(Bitboard& mask) {
   int sq = __builtin_ctzll(mask); // find least significant bit
   mask &= mask - 1; // clear least significant bit
   return sq;
}

如果我没记错的话,你现有的函数 bitScanForward 已经是一种实现查找最低有效位的方法。因此,你可以使用它来获得可移植版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接