const int BitTable[64] = {
63, 30, 3, 32, 25, 41, 22, 33, 15, 50, 42, 13, 11, 53, 19, 34, 61, 29, 2,
51, 21, 43, 45, 10, 18, 47, 1, 54, 9, 57, 0, 35, 62, 31, 40, 4, 49, 5, 52,
26, 60, 6, 23, 44, 46, 27, 56, 16, 7, 39, 48, 24, 59, 14, 12, 55, 38, 28,
58, 20, 37, 17, 36, 8
};
int pop_1st_bit(uint64 *bb) {
uint64 b = *bb ^ (*bb - 1);
unsigned int fold = (unsigned) ((b & 0xffffffff) ^ (b >> 32));
*bb &= (*bb - 1);
return BitTable[(fold * 0x783a9b23) >> 26];
}
uint64 index_to_uint64(int index, int bits, uint64 m) {
int i, j;
uint64 result = 0ULL;
for(i = 0; i < bits; i++) {
j = pop_1st_bit(&m);
if(index & (1 << i)) result |= (1ULL << j);
}
return result;
}
它来自国际象棋编程维基:
https://www.chessprogramming.org/Looking_for_Magics
这是一些用于查找magic numbers的代码的一部分。
参数uint64 m
是一个bitboard,表示车或象移动的可能的方块。e4广场上的车的示例:
0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 1 1 1 0 1 1 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0
边缘平方是零,因为它们总是阻塞的,减少所需的位数显然是有帮助的。
/* Bitboard, LSB to MSB, a1 through h8:
* 56 - - - - - - 63
* - - - - - - - -
* - - - - - - - -
* - - - - - - - -
* - - - - - - - -
* - - - - - - - -
* - - - - - - - -
* 0 - - - - - - 7
*/
因此,在上面的示例中,index_to_uint64
采用一个索引(0到2^位)、位板中设置的位数(10)和位板。
然后,它为每个位数执行pops_1st_bit
,然后是另一位变化无常的代码。pops_1st_bit
对位板进行减去1的XOR运算(为什么?)然后它以完整的32位对其进行and运算,然后在这里的某个地方,我的大脑耗尽了RAM。不知何故,涉及到了神奇的十六进制数字0x783a9b23 (这是Lost中的数字序列吗?)。还有这个荒谬的神秘数组,从0到63 (BitTable[64]
)随机排序的数字。
https://stackoverflow.com/questions/30680559
复制相似问题