summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-08-25 23:22:29 -0700
committerScott Gasch <[email protected]>2026-08-25 23:22:29 -0700
commit2245550e3c0344bcba093b24dc00f36b462fc940 (patch)
treeecef582eccd6588b0ca9d90fbaf76fe2fd1c2eef /src/chess.h
parentba803fe406ee2470aa461578f530d292380ec241 (diff)
Tame check-extension compounding; verified neutral in self-play (0.4955)
Fixes a real pathology: checks along a long unbroken forcing line could extend for free (net zero cost against the qsearch boundary), letting tree size blow up multiple orders of magnitude on positions like a near-all-check forced mate (ECM.089: 4.5B nodes / 31min at depth 12 before this change). - Main-search check extension: gate on SEE soundness (a losing sacrifice check gets a small consolation QUARTER_PLY instead of the full bonus a sound check gets), and flatten the sound-check bonus to a flat THREE_QUARTERS_PLY instead of a near-free ONE_PLY. - Lower the qsearch entry threshold to match (THREE_QUARTERS_PLY instead of ONE_PLY) so a lone check still buys one extra full-width ply as before; root.c trims QUARTER_PLY off the per-iteration depth budget so this doesn't add a blanket 1/4 ply to every search. - Qsearch's own check-widening (QSearchFromCheckNoStandPat) now relies on fCouldStandPat history plus a g_uIterateDepth/4 ceiling instead of an unconditional per-check grant, and QPLIES_OF_NON_CAPTURE_CHECKS moved from 1 to 2 to cover both "enter qsearch already in check" and "opponent's reply is the first real check" cases with one baseline window instead of ad hoc attacker-color tracking. Net effect on ECM.089 (sn 4M canary): ~7.5x fewer nodes and ~4x less time at depth 12 versus the original, unbounded behavior. Costs solve count on the full ECM suite (879 pos, sn 4M): 650 baseline -> 636 here -- expected and accepted, since ECM is unusually check-extension-heavy tactics and not representative of real games. Self-play vs baseline (1000 games, st 1) came back at B_SCORE=0.4955, ELO=-3.1+/-21.5 -- statistically neutral, confirming the fix costs nothing in real play. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/chess.h')
-rwxr-xr-xsrc/chess.h16
1 files changed, 2 insertions, 14 deletions
diff --git a/src/chess.h b/src/chess.h
index abf802e..8861ef1 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -819,10 +819,6 @@ typedef struct _COUNTERS
UINT64 u64LazyEvals;
UINT64 u64FullEvals;
UINT64 u64CyclesInEval;
- UINT64 u64HistoryPrunes;
- UINT64 u64HistoryPruneReSearches;
- UINT64 u64FutilityCandidates;
- UINT64 u64FutilityPrunes;
}
tree;
@@ -932,7 +928,6 @@ typedef struct _PLY_INFO
#endif
SCORE iEval;
INT iExtensionAmount;
- FLAG fIsPVNode; // (iBeta != iAlpha+1) at this ply
FLAG fInCheck;
FLAG fInQsearch;
MOVE mv;
@@ -2285,7 +2280,7 @@ IsDraw(SEARCHER_THREAD_CONTEXT *ctx);
//
// search.c
//
-#define QPLIES_OF_NON_CAPTURE_CHECKS (1)
+#define QPLIES_OF_NON_CAPTURE_CHECKS (2)
#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100)
#define DO_IID
#define IID_R_FACTOR (TWO_PLY + HALF_PLY)
@@ -2320,14 +2315,6 @@ ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx,
FLAG
ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *);
-void
-InitializeLMRTable(void);
-
-INT
-ExtraReduction(IN ULONG uRemainingDepth,
- IN ULONG uMoveNum,
- IN ULONG uFailHighPct);
-
FLAG
WeShouldDoHistoryPruning(IN SCORE iRoughEval,
IN SCORE iAlpha,
@@ -2377,6 +2364,7 @@ ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
IN ULONG uMoveNum,
IN SCORE iRoughEval,
IN ULONG uDepth,
+ IN SCORE iCheckSee,
IN OUT INT *piExtend);
SCORE