summaryrefslogtreecommitdiff
path: root/src/evalhash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evalhash.c')
-rw-r--r--src/evalhash.c148
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