It uses bitboard supersets anded together to form the attack bitboard.
Bishop on e4 Example:
8 _ _ _ _ _ _ _ _
7 _ _ _ _ _ _ _ x
6 _ _ x _ _ _ _ _
5 _ _ _ _ _ _ _ _
4 _ _ _ _ b _ _ _
3 _ _ _ x _ _ _ _
2 _ _ _ _ _ _ _ _
1 _ _ _ _ _ _ _ _
_ a b c d e f g h
If only the blocker on d3 was present the b_attacks would be:
8 x _ _ _ _ _ _ _
7 _ x _ _ _ _ _ x
6 _ _ x _ _ _ x _
5 _ _ _ x _ x _ _
4 _ _ _ _ _ _ _ _
3 _ _ _ x _ x _ _
2 _ _ _ _ _ _ x _
1 _ _ _ _ _ _ _ x
_ a b c d e f g h
if only the blocker on c6 ... :
8 _ _ _ _ _ _ _ _
7 _ _ _ _ _ _ _ x
6 _ _ x _ _ _ x _
5 _ _ _ x _ x _ _
4 _ _ _ _ _ _ _ _
3 _ _ _ x _ x _ _
2 _ _ x _ _ _ x _
1 _ x _ _ _ _ _ x
_ a b c d e f g h
if only the blocker on h7 ... :
8 x _ _ _ _ _ _ _
7 _ x _ _ _ _ _ x
6 _ _ x _ _ _ x _
5 _ _ _ x _ x _ _
4 _ _ _ _ _ _ _ _
3 _ _ _ x _ x _ _
2 _ _ x _ _ _ x _
1 _ x _ _ _ _ _ x
_ a b c d e f g h
Each one of these bitboards is a superset of the true attack bitboard, hence the Super Set part of the name.
When anded together they form the true attack bitboard.
8 _ _ _ _ _ _ _ _
7 _ _ _ _ _ _ _ x
6 _ _ x _ _ _ x _
5 _ _ _ x _ x _ _
4 _ _ _ _ _ _ _ _
3 _ _ _ x _ x _ _
2 _ _ _ _ _ _ x _
1 _ _ _ _ _ _ _ x
_ a b c d e f g h
Code: Select all
struct bbs {
u08 rank1;
u08 rank2;
u08 rank3;
u08 rank4;
u08 rank5;
u08 rank6;
u08 rank7;
u08 rank8;
};
union bbu {
bbs b08;
u64 b64;
};
void Initialize() {
u08 sq, sqr, i, j, k, l;
s08 x, dx, y, dy;
u64 b, bb;
for (sq = 0; sq < 64; sq++) { // for every square
y = sq >> 3; // decompose sq into x and y coordinates
x = sq & 7;
j = 0; // j as index, bss[64][j][6]
for (i = 0; i < 128; i++) { // for every rank of blockers
if (i ^ 1) { // only care if no bit zro blocker
bb = 0; // accumulator
for (k = 8, l = 0; k <= 48; k += 8, l++) { // for every rank of blockers, l as index
b = (u64)i << k; // shift blockers into position
for (dx = +1, dy = +1; x + dx < +8, y + dy < +8; dx++, dy++) { // progress along diagonal
sqr = (((y + dy) << 3) + x + dx); // compose square number
bb |= ONE << sqr; // accumulate bit
if (ONE << sqr & b) break; // if blocker then done with diagonal
}
for (dx = -1, dy = +1; x + dx > -1, y + dy < +8; dx--, dy++) {
sqr = (((y + dy) << 3) + x + dx);
bb |= ONE << sqr;
if (ONE << sqr & b) break;
}
for (dx = +1, dy = -1; x + dx < +8, y + dy > -1; dx++, dy--) {
sqr = (((y + dy) << 3) + x + dx);
bb |= ONE << sqr;
if (ONE << sqr & b) break;
}
for (dx = -1, dy = -1; x + dx > -1, y + dy > -1; dx--, dy--) {
sqr = (((y + dy) << 3) + x + dx);
bb |= ONE << sqr;
if (ONE << sqr & b) break;
}
}
bss[sq][j][l] = bb; // store the superset
j++; // next index
}
}
}
}
u64 BishopAttacks(u08 sq, bbu occ) {
occ.b64 = (occ.b64 << 1) & 0x00f3f3f3f3f3f300;
return
bss[sq][occ.b08.rank2][0] &
bss[sq][occ.b08.rank3][1] &
bss[sq][occ.b08.rank4][2] &
bss[sq][occ.b08.rank5][3] &
bss[sq][occ.b08.rank6][4] &
bss[sq][occ.b08.rank7][5];
}
Shared, rank table, between rook and queen 64 * 64 * 8 = 32768 bytes
rss[64][64][2], 64 * 64 * 8 = 65536 bytes
qss same as bishop 196,608 bytes
total = 196,608 + 32,768 + 65536 + 196,608 = 491,520 bytes
Queen:
Code: Select all
u64 QueenAttacks(u08 sq, bbu occ) {
u64 bb = rnk[sq][occ.b64 >> ((sq & 56) + 1) & 63];
occ.b64 = occ.b64 >> 1 & 0x00f3f3f3f3f3f300;
return bb &
qss[sq][occ.b08.rank2][0] &
qss[sq][occ.b08.rank3][1] &
qss[sq][occ.b08.rank4][2] &
qss[sq][occ.b08.rank5][3] &
qss[sq][occ.b08.rank6][4] &
qss[sq][occ.b08.rank7][5];
};