summaryrefslogtreecommitdiff
path: root/src/evalhash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evalhash.c')
-rw-r--r--src/evalhash.c84
1 files changed, 67 insertions, 17 deletions
diff --git a/src/evalhash.c b/src/evalhash.c
index e0bc75e..210c369 100644
--- a/src/evalhash.c
+++ b/src/evalhash.c
@@ -73,27 +73,48 @@ Return value:
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);
+ switch(ctx->rgEvalHash[u].bvFlags)
+ {
+ case EVAL_HASH_EXACT:
+ ctx->uPositional = ctx->rgEvalHash[u].uPositional;
+ return(ctx->rgEvalHash[u].iEval);
+ case EVAL_HASH_UPPER:
+ if (ctx->rgEvalHash[u].iBound <= iAlpha)
+ {
+ return(ctx->rgEvalHash[u].iEval);
+ }
+ break;
+ case EVAL_HASH_LOWER:
+ if (ctx->rgEvalHash[u].iBound >= iBeta)
+ {
+ return(ctx->rgEvalHash[u].iEval);
+ }
+ break;
+ }
}
}
return(pos->iMaterialBalance[pos->uToMove] + ctx->uPositional);
}
-SCORE
-ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx)
+SCORE
+ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx, IN SCORE iAlpha, IN SCORE iBeta)
/*++
Routine description:
Probe the eval hash; return a real score if there's a hit
- otherwise return INVALID_SCORE.
+ otherwise return INVALID_SCORE. An EXACT entry is always usable.
+ An UPPER/LOWER entry (recorded from a lazy-eval early exit) is
+ only usable if the bound it proved still resolves the caller's
+ current alpha/beta window; otherwise it's treated as a miss and
+ the caller must actually compute something.
Parameters:
IN OUT SEARCHER_THREAD_CONTEXT *ctx : note that in the case
of a hit, *ctx is modified also.
+ IN SCORE iAlpha, IN SCORE iBeta : caller's current window
Return value:
@@ -107,28 +128,52 @@ Return value:
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);
+ switch(ctx->rgEvalHash[u].bvFlags)
+ {
+ case EVAL_HASH_EXACT:
+ 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);
+ case EVAL_HASH_UPPER:
+ if (ctx->rgEvalHash[u].iBound <= iAlpha)
+ {
+ return(ctx->rgEvalHash[u].iEval);
+ }
+ break;
+ case EVAL_HASH_LOWER:
+ if (ctx->rgEvalHash[u].iBound >= iBeta)
+ {
+ return(ctx->rgEvalHash[u].iEval);
+ }
+ break;
+ }
}
return(INVALID_SCORE);
}
-void
-StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
- IN SCORE iScore)
+void
+StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
+ IN SCORE iScore,
+ IN SCORE iBound,
+ IN UCHAR bvFlags)
/*++
Routine description:
Store a score in the eval hash table (which is pointed to
- indirectly via ctx).
+ indirectly via ctx). bvFlags is EVAL_HASH_EXACT for a fully
+ computed eval (iBound ignored) or EVAL_HASH_UPPER/EVAL_HASH_LOWER
+ for a bound proven by a lazy-eval early exit (iScore is the
+ uncorrected partial score that would be returned, iBound is the
+ proven bound on the true eval).
Parameters:
SEARCHER_THREAD_CONTEXT *ctx,
- SCORE iScore
+ SCORE iScore,
+ SCORE iBound,
+ UCHAR bvFlags
Return value:
@@ -141,8 +186,13 @@ Return value:
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];
+ ctx->rgEvalHash[u].iBound = iBound;
+ ctx->rgEvalHash[u].bvFlags = bvFlags;
+ if (bvFlags == EVAL_HASH_EXACT)
+ {
+ 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