我刚刚开始编写国际象棋引擎,但最近刚刚完成了我的第一个程序。但它运行得很慢,所以我切换到了比特板,现在切换到了魔法比特板。我经常使用国际象棋编程维基。
我现在尝试一个测试位置和perft函数,看看程序每秒可以计算多少节点(包括批量计数)。现在,我的perft函数被设置为只计算伪合法移动,我已经设置make_move函数不切换回合。因此我可以用perft分析位置R7/8/8/8/8/8/8 w。
然而我的问题是,如果没有魔术比特板,我每秒得到622万个节点,而有了我只得到6.29。似乎我的魔术比特板没有正常工作。直觉上感觉魔术比特板的速度应该要大得多。此外,95%的计算时间花在我的伪合法移动生成器中。
正如我所提到的,我是国际象棋引擎的新手,尤其是魔术比特板。我不知道如何正确地完成搜寻列表,现在我有一个64*8192条目的表(用于rooks)。我在程序开始时初始化这个表,通过计算每个方块的所有不同的阻止器组合。然后我的索引由(occ给出
我缓慢的魔术比特板的原因是我巨大的表大小吗?有没有其他方法可以更有效地做到这一点?
速度如此之小的原因完全有可能是因为时间不是花在生成移动上,而是在不同的位板上迭代。有没有办法加快这个过程?似乎(通过谷歌搜索)我的功能
int ls1b(u64 bitboard) {
if (bitboard) {
return count((bitboard & -bitboard) - 1);
}
return -1;
}
和
int count(u64 bitboard) {
int count = 0;
while(bitboard) {
count++;
bitboard &= bitboard - 1;
}
return count;
}
尽可能快。stockfish(或其他c引擎)是如何进行这种迭代的?
我无法对程序的其余部分发表评论,因为我看不到它,但对于您的位函数,它们可以改进,请参见:
https://www.chessprogramming.org/BitScan#Trailing_Zero_Counthttps://en.wikipedia.org/wiki/Hamming_weight
int lsb(uint64_t bb) {
static const int lookup67[67+1] = {
64, 0, 1, 39, 2, 15, 40, 23,
3, 12, 16, 59, 41, 19, 24, 54,
4, -1, 13, 10, 17, 62, 60, 28,
42, 30, 20, 51, 25, 44, 55, 47,
5, 32, -1, 38, 14, 22, 11, 58,
18, 53, 63, 9, 61, 27, 29, 50,
43, 46, 31, 37, 21, 57, 52, 8,
26, 49, 45, 36, 56, 7, 48, 35,
6, 34, 33, -1 };
return lookup67[(bb & -bb) % 67];
}
const uint64_t m1 = 0x5555555555555555; //binary: 0101...
const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
int count(uint64_t x)
{
x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
return (x * h01) >> 56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}
DreamChess 是一款开放源码、跨平台(可在 Windows、Mac OS X 及 Linux 上运行)的 3D 国际象棋游戏。该游戏包含自身的引擎 Dreamer,提供各种国际象棋棋盘,并具有背景音乐及声效等其他附属功能。
我已经有一个Board对象,包含一个碎片列表。Piece是一个抽象类,有一个位置(x,y)和一个颜色(黑色或白色)。然后是King、Queen、Knight这三个类,实现了Piece类。 谢谢
我正在下国际象棋,除了一件事,我几乎得到了所有的东西:我需要使棋手不可能将棋子移动到棋盘上。我很难解决这个问题。 我现在用伪代码生成的有效移动是:类getMoveLocations(我定义了一个位置为国际象棋中的一个方块):如果这个位置在边界内,这个位置的棋子是敌人的棋子,并且模拟的移动不会导致棋盘被检查,然后将该位置添加到工件可以移动到的可能位置。 问题是我如何检查棋盘是否“在检查中”。在我的代
所以我一直在思考一个问题。我目前正在用Java编写一个基于比特板的国际象棋引擎(这是一个解决所有问题的过程)。到目前为止,所有的棋子/国王/骑士的动作都按预期进行,而且没有bug。 我需要帮助理解的是滑动件移动生成。我已经为每个方块/棋子生成了一系列空棋盘动作。根据我目前的理解,我还需要开发一个数组,包含每个广场上的每个可能占用空间——然后根据各种方法查找该数组。 这种想法正确吗?这是不是一个从0
我正在做一个项目,在那里我采取一个象棋棋盘位置(FEN字符串转换成二进制)&它的评估分数,并将它馈送给一个神经网络。我的目的是让神经网络区分好的和坏的仓位。 我是如何编码位置的:国际象棋中有12个独特的棋子,即棋子,棋子,骑士,主教,王后和国王,白棋和黑棋一样。我使用4位编码每一个片段,其中0000表示一个空的正方形。所以64个方块被编码成256位,我用另外6位来表示游戏状态,比如轮到谁移动,国王
上面的代码显示了一个可以上下移动的部分的示例。这不是一个有效的棋步。所以,如果我要移动一个皇后,我该怎么做呢?我们只是假设我们已经有了一个矩阵(x,y)8×8的板。