They work also with taboo squares, where some of the otherwise set bits are at zero because square is removed from attack set.
Code is somewhat optimized for 32 bit case. For 64 bit case we could spare some instruction.
Of interest there is the counting of bishops and knights attacks using _only one_ multiply instead of two (one per diagonal) as previously posted.
Following code is a working code and tested to be functionally identical to stock version.
Code: Select all
template<PieceType Piece>
inline int attack_count(Bitboard b, int sq) {
unsigned w = unsigned(b >> 32);
unsigned fl = sq & 7;
unsigned k = BitCount8Bit[w >> (24 + fl)];
b *=FileBB[7-fl];
w = unsigned(b >> 32);
unsigned first = unsigned(b >> (sq - fl)) & 0xFF;
unsigned top = w >> 24;
return BitCount8Bit[first] + BitCount8Bit[top - first] + k;
}
template<>
inline int attack_count<QUEEN>(Bitboard b, int) {
return count_1s(b);
}
template<>
inline int attack_count<ROOK>(Bitboard b, int sq) {
int fl = sq & 7;
unsigned w = unsigned((((b >> fl) & FileABB) * FileABB) >> 32);
return BitCount8Bit[unsigned(b >> (sq - fl)) & 0xFF] + (w >> 24);
}
FileBB[8] is an array of file bitboards indexed by the file. FileBB[x] is a bitboard with ones on the file x only.
int BitCount8Bit[256] is a table for looking up bit counts of a byte.
In case someone is interested in WHY it works and doesn't manage to understund it (it is not so trivial, especially the bishop case) please ask, I will post a little rationale of the formulas.