diff options
| author | Scott Gasch <[email protected]> | 2026-09-03 17:10:46 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-09-03 17:10:46 -0700 |
| commit | a8806adb87bac158353f851a9ad564941affd153 (patch) | |
| tree | 3a26a10caf08730c55e65869587c39921804813a | |
| parent | 6d76699e44f2ed0fb2368ccf0a19ae692a2d4697 (diff) | |
Fix draw-score bug in hash-hit path; centralize as g_iDrawScore[2]
Search()'s Dieter-Brusser hash-hit-leads-to-draw check only verified
that a score of 0 would clear the same alpha/beta bound as the stored
iScore -- it didn't establish that iScore itself was accurate. Since
playing the hash move actually produces a draw, propagate the draw
score upward instead of the stale score computed along a different,
non-repeating path.
While fixing this, centralized every other place that returned a
literal 0 for a draw (search.c's stalemate leaf, searchsup.c's
QSearch draw leaf, probe.c's EGTB draw case, which had a dead
`// g_iDrawValue[...]` comment suggesting this was intended all
along) into a single g_iDrawScore[2] global in draw.c, declared in
chess.h. It's indexed by side to move rather than a scalar so a
future contempt-factor tweak can bias the draw score per color
without touching every call site again; both entries are currently 0,
so behavior is unchanged except for the hash-hit bugfix above.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012e2SaEaQ27JJq1D3wCqryr
| -rwxr-xr-x | src/chess.h | 2 | ||||
| -rwxr-xr-x | src/draw.c | 2 | ||||
| -rw-r--r-- | src/probe.c | 2 | ||||
| -rwxr-xr-x | src/search.c | 20 | ||||
| -rw-r--r-- | src/searchsup.c | 2 |
5 files changed, 20 insertions, 8 deletions
diff --git a/src/chess.h b/src/chess.h index 7760920..062e3dc 100755 --- a/src/chess.h +++ b/src/chess.h @@ -2351,6 +2351,8 @@ ClearRootNodecountHash(void); // // draw.c // +extern SCORE g_iDrawScore[2]; + FLAG IsDraw(SEARCHER_THREAD_CONTEXT *ctx); @@ -22,6 +22,8 @@ Revision History: #include "chess.h" +SCORE g_iDrawScore[2] = {0, 0}; + FLAG IsDraw(SEARCHER_THREAD_CONTEXT *ctx) { diff --git a/src/probe.c b/src/probe.c index 242612c..2d59e5a 100644 --- a/src/probe.c +++ b/src/probe.c @@ -284,7 +284,7 @@ Return value: case TB_BLESSED_LOSS: case TB_DRAW: default: - *piScore = 0; // g_iDrawValue[pos->uToMove]; + *piScore = g_iDrawScore[pos->uToMove]; break; } fResult = TRUE; diff --git a/src/search.c b/src/search.c index 870951b..31220e1 100755 --- a/src/search.c +++ b/src/search.c @@ -275,15 +275,23 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, VERIFY(MakeMove(ctx, mvHash)); fIsDraw = IsDraw(ctx); UnmakeMove(ctx, mvHash); - if ((FALSE == fIsDraw) || (iScore == 0) || - ((u == HASH_FLAG_LOWER) && (iScore >= iBeta) && (0 >= iBeta)) || - ((u == HASH_FLAG_UPPER) && (iScore <= iAlpha) && (0 <= iAlpha))) + if ((FALSE == fIsDraw) || (iScore == g_iDrawScore[pos->uToMove]) || + ((u == HASH_FLAG_LOWER) && (iScore >= iBeta) && (g_iDrawScore[pos->uToMove] >= iBeta)) || + ((u == HASH_FLAG_UPPER) && (iScore <= iAlpha) && (g_iDrawScore[pos->uToMove] <= iAlpha))) { - if ((iAlpha < iScore) && (iScore < iBeta)) + // If the hash move leads to a draw, the score actually + // produced by playing it is g_iDrawScore[pos->uToMove] + // (from the mover's point of view), not the stale iScore + // recorded along whatever non-repeating path originally + // stored this entry -- the checks above only established + // that the draw score clears the same bound iScore does, + // not that iScore itself is an accurate value to return. + SCORE iRetScore = fIsDraw ? g_iDrawScore[pos->uToMove] : iScore; + if ((iAlpha < iRetScore) && (iRetScore < iBeta)) { UpdatePV(ctx, HASHMOVE); } - iBestScore = iScore; + iBestScore = iRetScore; goto end; } } @@ -949,7 +957,7 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, } else { - iBestScore = 0; + iBestScore = g_iDrawScore[pos->uToMove]; if ((iAlpha < iBestScore) && (iBestScore < iBeta)) { INC(ctx->sCounters.tree.u64LeafCount); diff --git a/src/searchsup.c b/src/searchsup.c index 172413f..b79db3a 100644 --- a/src/searchsup.c +++ b/src/searchsup.c @@ -1042,7 +1042,7 @@ Return value: if (TRUE == IsDraw(ctx)) { INC(ctx->sCounters.tree.u64LeafCount); - *piScore = 0; + *piScore = g_iDrawScore[ctx->sPosition.uToMove]; if ((*piAlpha < *piScore) && (*piScore < *piBeta)) { UpdatePV(ctx, DRAWMOVE); |
