This post is a follow up of this one: C++ vs Java Engine move generation performance
My goal here is to improve the performance of my move generator, which finishes perft (start_pos, 6) in 8.5 secs. That's too slow for C++ code (the same Java code runs in 11 secs).
The bottleneck is the check for validity, which in turn tests if the king is in check. This is running for every move, and given that most moves are legal, it's a total waste of time. As pointed out by Student T, we should restricted this test for king in check, pinned pieces and en passant captures.
The king in check or walking to check cases are easy, this post is about pinned pieces code. So, the cpwiki code goes like this:
pinned = 0;
pinner = xrayRookAttacks(occupiedBB, ownPieces, squareOfKing) & opRQ;
while ( pinner ) {
int sq = bitScanForward(pinner);
pinned |= obstructed(sq, squareOfKing) & ownPieces;
pinner &= pinner - 1;
}
pinner = xrayBishopAttacks(occupiedBB, ownPieces, squareOfKing) & opBQ;
while ( pinner ) {
int sq = bitScanForward(pinner);
pinned |= obstructed(sq, squareOfKing) & ownPieces;
pinner &= pinner - 1;
}
And here's the code for xrayRookAttacks():
U64 xrayRookAttacks(U64 occ, U64 blockers, enumSquare rookSq) {
U64 attacks = rookAttacks(occ, rookSq);
blockers &= attacks;
return attacks ^ rookAttacks(occ ^ blockers, rookSq);
}
Questions:
a) What is obstructed()
doing?
b) After getting the pinned
set, how exactly do I use it to test for a valid move?
Thank you all!