diff options
Diffstat (limited to 'src/poshash.c')
| -rw-r--r-- | src/poshash.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/src/poshash.c b/src/poshash.c new file mode 100644 index 0000000..e8f09b5 --- /dev/null +++ b/src/poshash.c @@ -0,0 +1,276 @@ +/*++ + +Copyright (c) Scott Gasch + +Module Name: + + poshash.c + +Abstract: + + A hash table of information about positions. + +Author: + + Scott Gasch (SGasch) 11 Nov 2006 + +Revision History: + +--*/ + +#include "chess.h" + +#define NUM_POSITION_HASH_ENTRIES (1048576) // 16Mb +POSITION_HASH_ENTRY g_PositionHash[NUM_POSITION_HASH_ENTRIES]; + +#ifdef MP +#define NUM_POSITION_HASH_LOCKS (512) +volatile static ULONG g_uPositionHashLocks[NUM_POSITION_HASH_LOCKS]; +#define POSITION_HASH_IS_LOCKED(x) ((g_uPositionHashLocks[(x)]) != 0) +#define LOCK_POSITION_HASH(x) \ + AcquireSpinLock(&(g_uPositionHashLocks[(x)])); \ + ASSERT(POSITION_HASH_IS_LOCKED(x)) +#define UNLOCK_POSITION_HASH(x) \ + ASSERT(POSITION_HASH_IS_LOCKED(x)); \ + ReleaseSpinLock(&(g_uPositionHashLocks[(x)])) +#else +#define POSITION_HASH_IS_LOCKED(x) +#define LOCK_HASH(x) +#define UNLOCK_HASH(x) +#endif + +void +InitializePositionHashSystem(void) +{ + memset(&g_PositionHash, 0, sizeof(g_PositionHash)); +#ifdef MP + memset(&g_uPositionHashLocks, 0, sizeof(g_uPositionHashLocks)); +#endif +} + +void +CleanupPositionHashSystem(void) +{ + ; // do nothing +} + +static INLINE UINT64 PositionToSignatureIgnoringMove(POSITION *pos) +{ + return((pos->u64NonPawnSig ^ pos->u64PawnSig) >> 1); +} + +// Note: sig must be pre-shifted to ignore the side-to-move bit. +static INLINE ULONG PositionSigToHashPosition(UINT64 u64Sig) +{ + ULONG u = (ULONG)u64Sig; + u &= (NUM_POSITION_HASH_ENTRIES - 1); + ASSERT(u < NUM_POSITION_HASH_ENTRIES); + return u; +} + +#ifdef MP +static INLINE ULONG HashPositionToLockNumber(ULONG u) +{ + u &= (NUM_POSITION_HASH_LOCKS - 1); + ASSERT(u < NUM_POSITION_HASH_LOCKS); + return u; +} +#endif + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + PIECE p = pos->rgSquare[cSquare].pPiece; + ULONG uColor = GET_COLOR(p); +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + ASSERT(p && IS_VALID_PIECE(p)); + ASSERT(!IS_PAWN(p)); + ASSERT(CAN_FIT_IN_UCHAR(cSquare)); + ASSERT(IS_ON_BOARD(cSquare)); + pHash->cEnprise[uColor] = (UCHAR)cSquare; + ASSERT(pHash->uEnpriseCount[uColor] < 16); + pHash->uEnpriseCount[uColor] += 1; + if (pHash->u64Sig != u64Sig) + { + pHash->u64Sig = u64Sig; + pHash->uEnpriseCount[uColor] = 1; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + uColor = FLIP(uColor); + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif +} + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + PIECE p = pos->rgSquare[cSquare].pPiece; + ULONG uColor = GET_COLOR(p); +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + ASSERT(p && IS_VALID_PIECE(p)); + ASSERT(!IS_PAWN(p)); + ASSERT(CAN_FIT_IN_UCHAR(cSquare)); + ASSERT(IS_ON_BOARD(cSquare)); + pHash->cTrapped[uColor] = cSquare; + if (pHash->u64Sig != u64Sig) + { + pHash->u64Sig = u64Sig; + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + uColor = FLIP(uColor); + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif +} + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + COOR c = ILLEGAL_COOR; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + c = pHash->cEnprise[uSide]; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return c; +} + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + COOR c = ILLEGAL_COOR; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + c = pHash->cTrapped[uSide]; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return c; +} + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + FLAG fStand = TRUE; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + fStand = ((pHash->cTrapped[uSide] == ILLEGAL_COOR) && + (pHash->uEnpriseCount[uSide] < 2)); + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return fStand; +} + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + ULONG u = 0; + COOR c; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + if (pHash->uEnpriseCount[uSide] > 1) + { + c = pHash->cEnprise[uSide]; + ASSERT(IS_ON_BOARD(c)); + u = PIECE_VALUE(pos->rgSquare[c].pPiece); + ASSERT(u); + } + c = pHash->cTrapped[uSide]; + if (IS_ON_BOARD(c)) + { + u = MAXU(u, PIECE_VALUE(pos->rgSquare[c].pPiece)); + ASSERT(u); + } + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return u; +} + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + ULONG u = 0; + COOR c; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + if (pHash->uEnpriseCount[uSide]) + { + c = pHash->cEnprise[uSide]; + ASSERT(IS_ON_BOARD(c)); + u += PIECE_VALUE(pos->rgSquare[c].pPiece); + ASSERT(u); + } + c = pHash->cTrapped[uSide]; + if (IS_ON_BOARD(c)) + { + u = MAXU(PIECE_VALUE(pos->rgSquare[c].pPiece), u); + ASSERT(u); + } + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return u; +} |
