diff options
| author | Scott Gasch <[email protected]> | 2026-08-28 08:29:09 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-08-28 08:29:09 -0700 |
| commit | 538df17868afff51d49927fb5c8a91724752f26c (patch) | |
| tree | a2f945d846fe9978ad64c487f6925df317b9e3b3 /src/search.c | |
| parent | eaed74ec737e5ac38a6c47d3f3d857d13a3153b3 (diff) | |
Fix _ShouldWeConsiderThisMove's SEE-purity bug and ComputeMoveScore's
killer-mate edge case; fix PV-display cycle hang.
_ShouldWeConsiderThisMove (QSearch's move-consider gate) read the raw,
move-ordering-biased mvf[].iValue directly instead of going through
ComputeMoveScore, so it inherited the same +120-ish flat bias (plus
small MVV-LVA nudges) on winning/even captures that ComputeMoveScore
was already fixed to strip out. Fixed via the same MOVE_SCORE_ORDERING_BIAS
subtraction, now factored into a shared chess.h macro. Restoring the old
effective leniency required an explicit QSEARCH_CONSIDER_MARGIN (120,
A/B'd against 0/60/120 on ecm_ringers/confident_quick/hard_quick) rather
than assuming the bug's magnitude was itself a meaningful margin -- net
effect vs the pre-fix baseline is -2 solves on hard_quick, accepted as
the cost of correctness (see lmr_testing/RESULTS.md for the full sweep).
ComputeMoveScore separately mishandled quiet killer-mate moves: they can
reach SORT_THESE_FIRST via generate.c's killer-mate bonus (unrelated to
the capture-bias path), so the bias-subtraction was wrongly applied to a
move that never had that bias. Gated the subtraction on
IS_CAPTURE_OR_PROMOTION(mv); quiet moves (including killer-mate ones) now
correctly collapse to 0, per the function's contract of estimating a
move's value on the 100=1-pawn axis. Measured as a no-op on all three
suites -- rare in practice, but a real correctness fix. Left a comment
documenting two candidate refinements for scoring quiet moves as
non-uniform future work, deliberately not implemented (each needs its
own isolated test).
FinishPVTailFromHash (cosmetic PV-display hash-walk, used only for
printing) had no cycle detection, so a drawish/repeating position could
spin until the output buffer filled instead of terminating naturally.
Added visited-position-signature tracking and a <REP> marker.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YGSMkwjqiCk4XhbfN7ugD2
Diffstat (limited to 'src/search.c')
| -rwxr-xr-x | src/search.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/search.c b/src/search.c index e0339cf..eb931bc 100755 --- a/src/search.c +++ b/src/search.c @@ -792,6 +792,8 @@ Return value: FALSE if it can be skipped **/ +#define QSEARCH_CONSIDER_MARGIN (120) + static FLAG INLINE _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, IN ULONG uMoveNum, @@ -827,6 +829,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, { i &= STRIP_OFF_FLAGS; ASSERT(i >= 0); + i -= MOVE_SCORE_ORDERING_BIAS(mv); if (mv.pCaptured) { // If there are very few pieces left on the board, @@ -859,7 +862,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, // penalty can make them look "futile" sometimes. if ((PIECE_VALUE(mv.pCaptured) == PIECE_VALUE(mvLast.pCaptured)) && - (i + 200 > iFutility)) + (i + 200 + QSEARCH_CONSIDER_MARGIN > iFutility)) { return(TRUE); } @@ -867,7 +870,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, // Otherwise, even if a move is even/winning, make sure it // brings the score up to at least somewhere near alpha. - if (i > iFutility) + if (i + QSEARCH_CONSIDER_MARGIN > iFutility) { return(TRUE); } |
