3 Copyright (c) Scott Gasch
11 Position signature code... the algorithm is a Zobrist hash scheme.
12 Every piece has a different 64-bit "seed" for every different
13 square. Plus some non-piece/location features of a position (such
14 as legal castling rights or the en passant location) have 64-bit
15 "seed" keys. The position's signature is the xor sum of all these
16 seeds. A position's pawn hash signature is the xor sum of all
17 pawn-related seeds. These signatures, once computed, can be
18 incrementally maintained by just xoring off the seed of a moving
19 piece's from location and xoring on the seed of its to location.
20 These signatures are used as the basis for the pawn hash and main
21 transposition table code.
29 $Id: sig.c 345 2007-12-02 22:56:42Z scott $
35 UINT64 g_u64SigSeeds[128][7][2];
36 UINT64 g_u64PawnSigSeeds[128][2];
37 UINT64 g_u64CastleSigSeeds[16];
38 UINT64 g_u64EpSigSeeds[9];
41 InitializeSigSystem(void)
46 Populate the arrays of signature keys (see above) used to generate
47 normal and pawn signatures for POSITIONs.
63 memset(g_u64SigSeeds, 0, sizeof(g_u64SigSeeds));
64 memset(g_u64PawnSigSeeds, 0, sizeof(g_u64PawnSigSeeds));
65 memset(g_u64CastleSigSeeds, 0, sizeof(g_u64CastleSigSeeds));
66 memset(g_u64EpSigSeeds, 0, sizeof(g_u64EpSigSeeds));
69 for (x = A; x <= H+1; x++)
76 g_u64EpSigSeeds[x] = (UINT64)uRandom << 32;
79 g_u64EpSigSeeds[x] |= uRandom;
80 g_u64EpSigSeeds[x] &= ~1;
84 // Foreach square on the board.
86 for (x = 0; x < 128; x++)
98 g_u64PawnSigSeeds[x][z] = (UINT64)uRandom << 32;
100 uRandom = randomMT();
101 uChecksum ^= uRandom;
102 g_u64PawnSigSeeds[x][z] |= uRandom;
103 g_u64PawnSigSeeds[x][z] &= ~1;
108 for (y = 0; y < 7; y++)
110 uRandom = randomMT();
111 uChecksum ^= uRandom;
112 g_u64SigSeeds[x][y][z] = (UINT64)uRandom << 32;
114 uRandom = randomMT();
115 uChecksum ^= uRandom;
116 g_u64SigSeeds[x][y][z] |= uRandom;
117 g_u64SigSeeds[x][y][z] &= ~1;
123 // For all castle permissions
125 for (x = 0; x < 16; x++)
127 uRandom = randomMT();
128 uChecksum ^= uRandom;
129 g_u64CastleSigSeeds[x] = (UINT64)uRandom << 32;
131 uRandom = randomMT();
132 uChecksum ^= uRandom;
133 g_u64CastleSigSeeds[x] |= uRandom;
134 g_u64CastleSigSeeds[x] &= ~1;
138 // Make sure we got what we expected.
140 if (uChecksum != 0xac19ab2b)
142 UtilPanic(DETECTED_INCORRECT_INITIALIZATION,
153 ComputePawnSig(POSITION *pos)
158 Given a board, recompute the pawn signature from scratch.
176 if (!IS_ON_BOARD(c)) continue;
178 p = pos->rgSquare[c].pPiece;
181 u64Sum ^= g_u64PawnSigSeeds[c][GET_COLOR(p)];
189 ComputeSig(POSITION *pos)
194 Given a board, recompute the main signature from scratch.
212 if (!IS_ON_BOARD(c)) continue;
214 p = pos->rgSquare[c].pPiece;
216 if (!IS_EMPTY(p) && !IS_PAWN(p))
218 ASSERT(IS_VALID_PIECE(p));
219 u64Sum ^= g_u64SigSeeds[c][PIECE_TYPE(p)][GET_COLOR(p)];
224 // Update the signature to reflect the castle permissions and ep
225 // square at this point.
227 u64Sum ^= g_u64CastleSigSeeds[pos->bvCastleInfo];
228 u64Sum ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)];
231 // Update the low order bit to reflect the side to move.
233 if (pos->uToMove == WHITE)
241 ASSERT((u64Sum & 1) == pos->uToMove);