summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-08-28 08:29:09 -0700
committerScott Gasch <[email protected]>2026-08-28 08:29:09 -0700
commit538df17868afff51d49927fb5c8a91724752f26c (patch)
treea2f945d846fe9978ad64c487f6925df317b9e3b3 /src/chess.h
parenteaed74ec737e5ac38a6c47d3f3d857d13a3153b3 (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/chess.h')
-rwxr-xr-xsrc/chess.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/chess.h b/src/chess.h
index 630f090..9b6303d 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -1652,6 +1652,18 @@ typedef struct _PIECE_DATA
extern PIECE_DATA g_PieceData[8];
#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100)
+
+// _ScoreAllMoves / _ScoreQSearchMoves{InclChecks,NoChecks} (generate.c) bake
+// a flat +120 move-ordering bias plus small MVV-LVA tie-break nudges into
+// winning/even captures'/promotions' iValue -- harmless for sorting, but
+// wrong once the value is used on the eval axis (compared against
+// material-scale margins). Back it out to recover the pure SEE/
+// material-diff value. ComputeMoveScore() (searchsup.c) already does this;
+// _ShouldWeConsiderThisMove() (search.c) reads iValue raw and needs it too.
+#define MOVE_SCORE_ORDERING_BIAS(mv) \
+ (PIECE_VALUE_OVER_100((mv).pCaptured) + 120 + \
+ PIECE_VALUE_OVER_100((mv).pPromoted) - \
+ PIECE_VALUE_OVER_100((mv).pMoved))
extern ULONG
PieceValueOver100(PIECE p);