From ba803fe406ee2470aa461578f530d292380ec241 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Tue, 25 Aug 2026 14:03:46 -0700 Subject: Add LMR with PV-adjacency guard (v7), verified against saved binary Late Move Reductions using a depth x movecount table (Ethereal-style formula), gated off PV nodes and the ply directly below a PV node (PLY_INFO.fIsPVNode), with magnitude-aware re-search on fail-high. Verified node-for-node identical to the previously tested-good v7 binary on a canary position (sd 10) after reconstructing from a ZFS snapshot of search.c/root.c/split.c taken just before that binary was built. Co-Authored-By: Claude Sonnet 5 --- src/searchsup.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) (limited to 'src/searchsup.c') diff --git a/src/searchsup.c b/src/searchsup.c index 9e842d4..7af1a18 100644 --- a/src/searchsup.c +++ b/src/searchsup.c @@ -18,6 +18,7 @@ Revision History: **/ +#include #include "chess.h" extern SCORE g_iRootScore[2]; @@ -224,7 +225,8 @@ Return value: ASSERT((uMoveNum > 0) || (uLegalMoves == 0)); if ((uRemainingDepth >= TWO_PLY) && (iBeta == (iAlpha + 1)) && - (uLegalMoves > 5) && + (FALSE == ctx->sPlyInfo[ctx->uPly - 1].fIsPVNode) && + (uLegalMoves > 3) && (0 == iExtend) && // (iRoughEval + ComputeMoveScore(ctx, mv, uMoveNum - 1) + 200 < iAlpha) && (!IS_ESCAPING_CHECK(mv)) && @@ -244,10 +246,66 @@ Return value: } +#define LMR_TABLE_MAX_DEPTH 32 +#define LMR_TABLE_MAX_MOVES 63 + +static INT g_iLMRTable[LMR_TABLE_MAX_DEPTH + 1][LMR_TABLE_MAX_MOVES + 1]; + +void +InitializeLMRTable(void) +{ + ULONG d, m; + double r; + + g_iLMRTable[0][0] = 0; + for (d = 0; d <= LMR_TABLE_MAX_DEPTH; d++) + { + for (m = 0; m <= LMR_TABLE_MAX_MOVES; m++) + { + if ((d < 1) || (m < 1)) + { + g_iLMRTable[d][m] = 0; + continue; + } + r = 0.7844 + (log((double)d) * log((double)m) / 2.4696); + if (r < 0.0) r = 0.0; + g_iLMRTable[d][m] = (INT)((r * ONE_PLY) + 0.5); + } + } +} + + +INT +ExtraReduction(IN ULONG uRemainingDepth, + IN ULONG uMoveNum, + IN ULONG uFailHighPct) +{ + INT iExtra; + ULONG d = uRemainingDepth / ONE_PLY; + ULONG m = uMoveNum; + + if (d > LMR_TABLE_MAX_DEPTH) d = LMR_TABLE_MAX_DEPTH; + if (m > LMR_TABLE_MAX_MOVES) m = LMR_TABLE_MAX_MOVES; + iExtra = g_iLMRTable[d][m]; + + if (uFailHighPct == 0) + { + iExtra += QUARTER_PLY; + } + + if ((INT)uRemainingDepth - ONE_PLY - iExtra < TWO_PLY) + { + iExtra = MAX((INT)uRemainingDepth - ONE_PLY - TWO_PLY, 0); + } + ASSERT(iExtra >= 0); + return(iExtra); +} + + SCORE ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, IN MOVE mv, - IN ULONG uMoveNum) + IN ULONG uMoveNum) { SCORE iMoveScore = (PIECE_VALUE(mv.pCaptured) + PIECE_VALUE(mv.pPromoted)); -- cgit v1.3