Hiding the Implementation
None rotated approaches as mentioned in
- Classical Approach
- Rank Attacks
- Hyperbola Quintessence
- Obstruction Difference
- Kindergarten Bitboards
- Magic Bitboards
- The Switch Approach
- SIMD Techniques
can hide the implementation details behind a stateless interface:
U64 diagonalAttacks(U64 occ, enumSquare sq); U64 antiDiagAttacks(U64 occ, enumSquare sq); U64 fileAttacks (U64 occ, enumSquare sq); U64 rankAttacks (U64 occ, enumSquare sq); U64 rookAttacks (U64 occ, enumSquare sq); U64 bishopAttacks (U64 occ, enumSquare sq); U64 queenAttacks (U64 occ, enumSquare sq);
In C / C++ one may use header files with exclusive, conditional compiled inlined routines, as combinations and variations of the mentioned approaches. Initialization should be implemented by conditional compile switches in various implementation files (c, cpp). Favorite should be bishopAttack by magic bitboards due to the relative small table less than 38KByte, while magic rookattacks takes more than 20 times the space so far.
As always with space-time tradeoff - it depends on the cache- and memory using and footprint of a individual chess program - on a particular hardware architecture - which solution is preferable and faster. Perft frameworks likely prefer larger tables but less computation. So far L1 Cache is a rare resource, Translation Lookaside Buffer als well.