The Color of a Square of a 8x8 board may be determined by several approaches. Since the number of files (and ranks) is even, and black and white colors alternate on consecutive ranks (and files), one can not use the simple parity of the combined square index in the 0..63 range. Applications are mostly related square color bounded bishops, for instance to find the right corners in KBNK Endgame.
By Lookup
The obvious approach is a memory lookup of a pre-calculated 64 byte array, containing the color of each square index. Alternatively one may use an In-Register Lookup, using a constant Bitboard representing all dark squares.
Another approach is based on whether the anti-diagonal index (sum of rank and files) is odd or even. An even index (bit 0 clear) implies a black or dark square, an odd index light or white squares. Since we need to mask off the least significant bit only, we can save masking off the file from square, because upper bits have no influence on bit zero anyway. To be conform with the arbitrary color definition (black == 1 rather than 0), one additional toggleColor, aka xor with '1' is necessary:
The same tricks might be applied to determine two squares have the same color or not. If the sum of both anti-diagonal indices is odd, the color is different. Using xor (sq1 ^= sq2) to 'add' ranks and files simultaneously or SWAR-wise without possible overflows saves one instruction.
Alternatively, if one has a Knight-Distance 64 x 64 array, one may use the least significant bit, since all even Knight-Distances between squares imply same square color.
Table of Contents
The Color of a Square of a 8x8 board may be determined by several approaches. Since the number of files (and ranks) is even, and black and white colors alternate on consecutive ranks (and files), one can not use the simple parity of the combined square index in the 0..63 range. Applications are mostly related square color bounded bishops, for instance to find the right corners in KBNK Endgame.
By Lookup
The obvious approach is a memory lookup of a pre-calculated 64 byte array, containing the color of each square index. Alternatively one may use an In-Register Lookup, using a constant Bitboard representing all dark squares.Shifting right this bitboard by square index, and masking off the least significant bit, leaves the square color:
On x86 one may use a shorter 32-bit constant and 32-bit shift, since the 32-bit shift is implicitly modulo 32 ... [1]
... which also works for 0x88 coordinates, since the In-Register lookup covers one even and odd 16-bit rank.
By Anti-Diagonal Index
Another approach is based on whether the anti-diagonal index (sum of rank and files) is odd or even. An even index (bit 0 clear) implies a black or dark square, an odd index light or white squares. Since we need to mask off the least significant bit only, we can save masking off the file from square, because upper bits have no influence on bit zero anyway. To be conform with the arbitrary color definition (black == 1 rather than 0), one additional toggleColor, aka xor with '1' is necessary:Same applies for the diagonal index as well (difference of rank and files), thus one can replace 'plus' by 'minus' or 'exclusive or', as shown in bitwise arithmetic.
A small transformation may save one register ...
... with following x86 assembly in mind:
A boolean condition even saves the shift, but tests bit 3:
... with this assembly in mind:
Same color
The same tricks might be applied to determine two squares have the same color or not. If the sum of both anti-diagonal indices is odd, the color is different. Using xor (sq1 ^= sq2) to 'add' ranks and files simultaneously or SWAR-wise without possible overflows saves one instruction.The mentioned lea-transformation saves one register and shift, if one jumps conditionally anyway...
... also for the complement expression:
Alternatively, if one has a Knight-Distance 64 x 64 array, one may use the least significant bit, since all even Knight-Distances between squares imply same square color.
See also
References
What links here?
Up one Level