diff options
Diffstat (limited to 'src/data.c')
| -rwxr-xr-x | src/data.c | 157 |
1 files changed, 157 insertions, 0 deletions
@@ -563,3 +563,160 @@ InitializeDistanceTable(void) } #endif } + +// +// Per-square, per-direction "ray to board edge" bitboards for the +// rook, indexed [direction][c] with direction matching +// g_RookRayDeltas below (N, S, E, W). Only entries for real board +// squares (IS_ON_BOARD(c)) are ever populated/queried; off-board +// indices are left zeroed and unused. Built once at startup by +// InitializeRookRayTables() -- part of eval.c's occupancy-bitboard +// PoC (_EvalRookOccupancyBB et al.), turning a per-call +// walk-to-the-edge loop into an O(1) table lookup. +// +BITBOARD g_RookRayToEdge[4][128]; +const int g_RookRayDeltas[4] = { 16, -16, 1, -1 }; // N, S, E, W (0x88) +const FLAG g_RookRayPositiveDir[4] = { TRUE, FALSE, TRUE, FALSE }; + +void +InitializeRookRayTables(void) +/** + +Routine description: + + One-time startup init for g_RookRayToEdge -- see its comment. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG uRank, uFile, uDir; + COOR c, cSquare; + + memset(g_RookRayToEdge, 0, sizeof(g_RookRayToEdge)); + for (uRank = 0; uRank < 8; uRank++) + { + for (uFile = 0; uFile < 8; uFile++) + { + c = (uRank << 4) | uFile; + for (uDir = 0; uDir < 4; uDir++) + { + for (cSquare = c + g_RookRayDeltas[uDir]; + IS_ON_BOARD(cSquare); + cSquare += g_RookRayDeltas[uDir]) + { + g_RookRayToEdge[uDir][c] |= COOR_TO_BB(cSquare); + } + } + } + } +} + +// +// Same idea as g_RookRayToEdge, for the bishop's 4 diagonal directions. +// +BITBOARD g_BishopRayToEdge[4][128]; +const int g_BishopRayDeltas[4] = { 17, -17, 15, -15 }; // NE, SW, NW, SE (0x88) +const FLAG g_BishopRayPositiveDir[4] = { TRUE, FALSE, TRUE, FALSE }; + +void +InitializeBishopRayTables(void) +/** + +Routine description: + + One-time startup init for g_BishopRayToEdge -- see its comment. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG uRank, uFile, uDir; + COOR c, cSquare; + + memset(g_BishopRayToEdge, 0, sizeof(g_BishopRayToEdge)); + for (uRank = 0; uRank < 8; uRank++) + { + for (uFile = 0; uFile < 8; uFile++) + { + c = (uRank << 4) | uFile; + for (uDir = 0; uDir < 4; uDir++) + { + for (cSquare = c + g_BishopRayDeltas[uDir]; + IS_ON_BOARD(cSquare); + cSquare += g_BishopRayDeltas[uDir]) + { + g_BishopRayToEdge[uDir][c] |= COOR_TO_BB(cSquare); + } + } + } + } +} + +// A combined 8-ray queen table (rook's 4 directions + bishop's 4, +// concatenated) was tried here and measured SLOWER than +// _EvalQueenOccupancyBB's two-pass version reusing g_RookRayToEdge/ +// g_BishopRayToEdge directly -- see that function's comment for why +// (probable lost constant-folding on the orthogonal-ray flag). Removed +// rather than left around unused. + +// +// Per-square "all squares a knight on c can hop to" bitboard. Unlike +// the rook/bishop ray tables, a knight has no blocking to account for +// -- there's nothing "in between" a knight and its landing square -- +// so this is the complete, final answer for a given square, not a +// ray-to-edge that still needs an occupancy AND to find blockers. +// Built once at startup by InitializeKnightAttackTables(). +// +BITBOARD g_KnightAttacksBB[128]; + +void +InitializeKnightAttackTables(void) +/** + +Routine description: + + One-time startup init for g_KnightAttacksBB -- see its comment. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG uRank, uFile, uDir; + COOR c, cSquare; + + memset(g_KnightAttacksBB, 0, sizeof(g_KnightAttacksBB)); + for (uRank = 0; uRank < 8; uRank++) + { + for (uFile = 0; uFile < 8; uFile++) + { + c = (uRank << 4) | uFile; + for (uDir = 0; g_iNDeltas[uDir] != 0; uDir++) + { + cSquare = c + g_iNDeltas[uDir]; + if (IS_ON_BOARD(cSquare)) + { + g_KnightAttacksBB[c] |= COOR_TO_BB(cSquare); + } + } + } + } +} |
