3 Copyright (c) Scott Gasch
11 A hash table of information about positions.
15 Scott Gasch (SGasch) 11 Nov 2006
23 #define NUM_POSITION_HASH_ENTRIES (1048576) // 16Mb
24 POSITION_HASH_ENTRY g_PositionHash[NUM_POSITION_HASH_ENTRIES];
27 #define NUM_POSITION_HASH_LOCKS (512)
28 volatile static ULONG g_uPositionHashLocks[NUM_POSITION_HASH_LOCKS];
29 #define POSITION_HASH_IS_LOCKED(x) ((g_uPositionHashLocks[(x)]) != 0)
30 #define LOCK_POSITION_HASH(x) \
31 AcquireSpinLock(&(g_uPositionHashLocks[(x)])); \
32 ASSERT(POSITION_HASH_IS_LOCKED(x))
33 #define UNLOCK_POSITION_HASH(x) \
34 ASSERT(POSITION_HASH_IS_LOCKED(x)); \
35 ReleaseSpinLock(&(g_uPositionHashLocks[(x)]))
37 #define POSITION_HASH_IS_LOCKED(x)
39 #define UNLOCK_HASH(x)
43 InitializePositionHashSystem(void)
45 memset(&g_PositionHash, 0, sizeof(g_PositionHash));
47 memset(&g_uPositionHashLocks, 0, sizeof(g_uPositionHashLocks));
52 CleanupPositionHashSystem(void)
57 static INLINE UINT64 PositionToSignatureIgnoringMove(POSITION *pos)
59 return((pos->u64NonPawnSig ^ pos->u64PawnSig) >> 1);
62 // Note: sig must be pre-shifted to ignore the side-to-move bit.
63 static INLINE ULONG PositionSigToHashPosition(UINT64 u64Sig)
65 ULONG u = (ULONG)u64Sig;
66 u &= (NUM_POSITION_HASH_ENTRIES - 1);
67 ASSERT(u < NUM_POSITION_HASH_ENTRIES);
72 static INLINE ULONG HashPositionToLockNumber(ULONG u)
74 u &= (NUM_POSITION_HASH_LOCKS - 1);
75 ASSERT(u < NUM_POSITION_HASH_LOCKS);
81 StoreEnprisePiece(POSITION *pos, COOR cSquare)
83 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
84 ULONG uEntry = PositionSigToHashPosition(u64Sig);
85 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
86 PIECE p = pos->rgSquare[cSquare].pPiece;
87 ULONG uColor = GET_COLOR(p);
89 ULONG uLock = HashPositionToLockNumber(uEntry);
90 LOCK_POSITION_HASH(uLock);
92 ASSERT(p && IS_VALID_PIECE(p));
94 ASSERT(CAN_FIT_IN_UCHAR(cSquare));
95 ASSERT(IS_ON_BOARD(cSquare));
96 pHash->cEnprise[uColor] = (UCHAR)cSquare;
97 ASSERT(pHash->uEnpriseCount[uColor] < 16);
98 pHash->uEnpriseCount[uColor] += 1;
99 if (pHash->u64Sig != u64Sig)
101 pHash->u64Sig = u64Sig;
102 pHash->uEnpriseCount[uColor] = 1;
103 pHash->cTrapped[uColor] = ILLEGAL_COOR;
104 uColor = FLIP(uColor);
105 pHash->cEnprise[uColor] = ILLEGAL_COOR;
106 pHash->cTrapped[uColor] = ILLEGAL_COOR;
107 pHash->uEnpriseCount[uColor] = 0;
110 UNLOCK_POSITION_HASH(uLock);
115 StoreTrappedPiece(POSITION *pos, COOR cSquare)
117 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
118 ULONG uEntry = PositionSigToHashPosition(u64Sig);
119 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
120 PIECE p = pos->rgSquare[cSquare].pPiece;
121 ULONG uColor = GET_COLOR(p);
123 ULONG uLock = HashPositionToLockNumber(uEntry);
124 LOCK_POSITION_HASH(uLock);
126 ASSERT(p && IS_VALID_PIECE(p));
128 ASSERT(CAN_FIT_IN_UCHAR(cSquare));
129 ASSERT(IS_ON_BOARD(cSquare));
130 pHash->cTrapped[uColor] = cSquare;
131 if (pHash->u64Sig != u64Sig)
133 pHash->u64Sig = u64Sig;
134 pHash->cEnprise[uColor] = ILLEGAL_COOR;
135 pHash->uEnpriseCount[uColor] = 0;
136 uColor = FLIP(uColor);
137 pHash->cEnprise[uColor] = ILLEGAL_COOR;
138 pHash->cTrapped[uColor] = ILLEGAL_COOR;
139 pHash->uEnpriseCount[uColor] = 0;
142 UNLOCK_POSITION_HASH(uLock);
147 GetEnprisePiece(POSITION *pos, ULONG uSide)
149 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
150 ULONG uEntry = PositionSigToHashPosition(u64Sig);
151 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
152 COOR c = ILLEGAL_COOR;
154 ULONG uLock = HashPositionToLockNumber(uEntry);
155 LOCK_POSITION_HASH(uLock);
157 if (pHash->u64Sig == u64Sig)
159 c = pHash->cEnprise[uSide];
162 UNLOCK_POSITION_HASH(uLock);
168 GetTrappedPiece(POSITION *pos, ULONG uSide)
170 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
171 ULONG uEntry = PositionSigToHashPosition(u64Sig);
172 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
173 COOR c = ILLEGAL_COOR;
175 ULONG uLock = HashPositionToLockNumber(uEntry);
176 LOCK_POSITION_HASH(uLock);
178 if (pHash->u64Sig == u64Sig)
180 c = pHash->cTrapped[uSide];
183 UNLOCK_POSITION_HASH(uLock);
189 SideCanStandPat(POSITION *pos, ULONG uSide)
191 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
192 ULONG uEntry = PositionSigToHashPosition(u64Sig);
193 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
196 ULONG uLock = HashPositionToLockNumber(uEntry);
197 LOCK_POSITION_HASH(uLock);
199 if (pHash->u64Sig == u64Sig)
201 fStand = ((pHash->cTrapped[uSide] == ILLEGAL_COOR) &&
202 (pHash->uEnpriseCount[uSide] < 2));
205 UNLOCK_POSITION_HASH(uLock);
211 ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide)
213 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
214 ULONG uEntry = PositionSigToHashPosition(u64Sig);
215 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
219 ULONG uLock = HashPositionToLockNumber(uEntry);
220 LOCK_POSITION_HASH(uLock);
222 if (pHash->u64Sig == u64Sig)
224 if (pHash->uEnpriseCount[uSide] > 1)
226 c = pHash->cEnprise[uSide];
227 ASSERT(IS_ON_BOARD(c));
228 u = PIECE_VALUE(pos->rgSquare[c].pPiece);
231 c = pHash->cTrapped[uSide];
234 u = MAXU(u, PIECE_VALUE(pos->rgSquare[c].pPiece));
239 UNLOCK_POSITION_HASH(uLock);
245 ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide)
247 UINT64 u64Sig = PositionToSignatureIgnoringMove(pos);
248 ULONG uEntry = PositionSigToHashPosition(u64Sig);
249 POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]);
253 ULONG uLock = HashPositionToLockNumber(uEntry);
254 LOCK_POSITION_HASH(uLock);
256 if (pHash->u64Sig == u64Sig)
258 if (pHash->uEnpriseCount[uSide])
260 c = pHash->cEnprise[uSide];
261 ASSERT(IS_ON_BOARD(c));
262 u += PIECE_VALUE(pos->rgSquare[c].pPiece);
265 c = pHash->cTrapped[uSide];
268 u = MAXU(PIECE_VALUE(pos->rgSquare[c].pPiece), u);
273 UNLOCK_POSITION_HASH(uLock);