I de-obfuscated the code to understand what it does. Here's an alternative way to write it:lithander wrote: ↑Wed Oct 13, 2021 5:22 pm ...but it seems that indeed for the bishops there's no simple solution like for the rooks.
Code: Select all
U64 diagonalMask(int sq) { const U64 maindia = C64(0x8040201008040201); int diag =8*(sq & 7) - (sq & 56); int nort = -diag & ( diag >> 31); int sout = diag & (-diag >> 31); return (maindia >> sout) << nort; } U64 antiDiagMask(int sq) { const U64 maindia = C64(0x0102040810204080); int diag =56- 8*(sq&7) - (sq&56); int nort = -diag & ( diag >> 31); int sout = diag & (-diag >> 31); return (maindia >> sout) << nort; }
Code: Select all
int rank = square / 8;
int file = square & 7;
const ulong DIAGONAL = 0x8040201008040201UL;
int verticalShift = file - rank;
int bitShift = verticalShift << 3;//to shift one rank means to shift by 8 bits
ulong bbDiagonal = bitShift > 0 ? DIAGONAL >> bitShift : DIAGONAL << -bitShift;
const ulong ANTIDIAGONAL = 0x0102040810204080;
verticalShift = 7 - file - rank;
bitShift = verticalShift << 3;//to shift one rank means to shift by 8 bits
ulong bbAntiDiagonal = bitShift > 0 ? ANTIDIAGONAL >> bitShift : ANTIDIAGONAL << -bitShift;If you think in terms of files and ranks the computation of the value to shift by is a little more intuitive to understand.
Once you know the amount of ranks to shift by multiply with 8 (or shift by 3) because each rank is actually 8 squares.
Now you can't pass a negative 2nd operand to a right-shift. You have to use a left shift. Easily expressed with the ternary operator.
My curiosity is sated. Now what to do in the actual move generator of a competitive engine is a completely different question of course. And aesthetically I really like Mergi's solution with the 15-slot lookup table.
