I'd like to revisit SISSY bitboards. I think that they can be highly optimised just using C without resorting to assembly. Just considering the bishop for now. Code from the Chess Programming Wiki.
Code: Select all
U64 bss[6][64][64]; // 192 K
U64 bishopAttacks(U64 occ, enumSquare sq) {
return
bss[0][sq][(occ >> 9) & 63] & // 2nd rank
bss[1][sq][(occ >> 17) & 63] &
bss[2][sq][(occ >> 25) & 63] &
bss[3][sq][(occ >> 33) & 63] &
bss[4][sq][(occ >> 41) & 63] &
bss[5][sq][(occ >> 49) & 63] ; // 7th rank
}
I agree that is a little expensive. HOWEVER, that can be reduced to only two lookups! First shift the upper 32 bits of the occupancy up by 8 bits. Then and it with the lower 32 bits and then shift the 4th rank down by either 8 or 16 bits depending on the from square. That will produce a split index between the 2nd and third ranks. That is a whole lot of saved shifting and anding. The problem I'm having is the initializing everything into two ranks. I have correct working code that initializes for 6 ranks. Now I just need to do a second level of combining those values into 2 ranks.
Code: Select all
void InitializeB() {
u08 sq, sqr, i, j, k, l;
s08 x, dx, y, dy;
u64 b, bb;
for (sq = 0; sq < 64; sq++) {
y = sq >> 3;
x = sq & 7;
for (i = 0; i < 128; i++) {
if (i ^ 1) {
j = i >> 1;
for (k = 8, l = 0; k <= 48; k += 8, l++) {
bb = 0;
b = (u64)i << k;
for (dx = +1, dy = +1; x + dx < +8 && 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 > -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;
}
}
}
}
}
And as can be seen the initialisation to 6 ranks is not that long nor very difficult. But further reducing them down to two ranks is giving me too much trouble. Mar showed that SISSY was not that far away from magic to begin with. Isn't it worth further investigation?
The queen is also extremely promising. Here is my code from Bricabrac. Perft numbers are accurate so the accuracy has been verified in Bricabrac and by Mar.
Code: Select all
case WQ:
case BQ:
bb = qss[fs][(aPieces >> (fs & 56)) & 127][0]
& qss[fs][(aPieces >> 8) & 255][1]
& qss[fs][(aPieces >> 16) & 255][2]
& qss[fs][(aPieces >> 24) & 255][3]
& qss[fs][(aPieces >> 32) & 255][4]
& qss[fs][(aPieces >> 40) & 255][5]
& qss[fs][(aPieces >> 48) & 255][6]
& notme;
As can be seen the code has already been optimised a little by embedding a rank lookup into the existing queen table thus reducing the lookups to 7 instead of the wiki's 8. THEN if the rank is removed and the file is shifted to the a file like in the wiki all that is left is the diagonals that can be manipulated into 2 ranks. That reduces the 7 kind of expensive lookups down to only 3 plus the rank lookup similar to Gerd's Kindergarten bitboards. The Queen was already competitive with magic and maybe even better. The rook also seems promising if handled like the wiki suggest.
https://www.chessprogramming.org/SISSY_Bitboards
Can someone explain to me why there has been no interest in seeing what SISSY bitboards could become? I have to say, I just don't understand.