diff options
Diffstat (limited to 'src/evalhash.c')
| -rw-r--r-- | src/evalhash.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/evalhash.c b/src/evalhash.c new file mode 100644 index 0000000..e0bc75e --- /dev/null +++ b/src/evalhash.c @@ -0,0 +1,148 @@ +/*++ + +Copyright (c) Scott Gasch + +Module Name: + + evalhash.c + +Abstract: + + Evaluation score hashing code. + +Author: + + Scott Gasch ([email protected]) 11 Jul 2006 + +Revision History: + +--*/ + +#include "chess.h" +#ifdef EVAL_HASH + +extern ULONG g_uIterateDepth; + +SCORE +GetRoughEvalScore(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash) +/*++ + +Routine description: + + This is meant to be the "one place" that code looks when it needs to + get an idea of the estimated evaluation of a position (in mid tree, + not at the leaves... at the leaves just call Eval directly). + + The thought is that: + + 1. The top of the tree (near the root) represents very few nodes + which have big subtrees. Use the real Eval here. + + 2. Otherwise possibly probe the eval hash -- if there's a score in + it then we can return quickly. + + 3. Otherwise do a (very) rough material estimate. + +Parameters: + + IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash + +Return value: + + SCORE + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key; + ULONG u; + + if (ctx->uPly <= 4) + { + return Eval(ctx, iAlpha, iBeta); + } + else if ((fUseHash) || (ctx->uPly <= (g_uIterateDepth / 2))) + { + u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + if (ctx->rgEvalHash[u].u64Key == u64Key) + { + ctx->uPositional = ctx->rgEvalHash[u].uPositional; + return(ctx->rgEvalHash[u].iEval); + } + } + return(pos->iMaterialBalance[pos->uToMove] + ctx->uPositional); +} + + +SCORE +ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx) +/*++ + +Routine description: + + Probe the eval hash; return a real score if there's a hit + otherwise return INVALID_SCORE. + +Parameters: + + IN OUT SEARCHER_THREAD_CONTEXT *ctx : note that in the case + of a hit, *ctx is modified also. + +Return value: + + SCORE + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + + if (ctx->rgEvalHash[u].u64Key == u64Key) + { + ctx->uPositional = ctx->rgEvalHash[u].uPositional; + pos->cTrapped[WHITE] = ctx->rgEvalHash[u].cTrapped[WHITE]; + pos->cTrapped[BLACK] = ctx->rgEvalHash[u].cTrapped[BLACK]; + return(ctx->rgEvalHash[u].iEval); + } + return(INVALID_SCORE); +} + +void +StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iScore) +/*++ + +Routine description: + + Store a score in the eval hash table (which is pointed to + indirectly via ctx). + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iScore + +Return value: + + void + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + ctx->rgEvalHash[u].u64Key = u64Key; + ctx->rgEvalHash[u].iEval = iScore; + ctx->rgEvalHash[u].uPositional = ctx->uPositional; + ctx->rgEvalHash[u].cTrapped[WHITE] = pos->cTrapped[WHITE]; + ctx->rgEvalHash[u].cTrapped[BLACK] = pos->cTrapped[BLACK]; +} +#endif // EVAL_HASH |
