summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/chess.h')
-rwxr-xr-xsrc/chess.h76
1 files changed, 73 insertions, 3 deletions
diff --git a/src/chess.h b/src/chess.h
index b6175f7..137344f 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -783,6 +783,11 @@ MOVE_STACK;
((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces)
+// EXPERIMENT: see the fuller comment near COUNTERMOVE_TIER_BONUS below.
+// Needs to be visible before COUNTERS/GAME_OPTIONS, which use it to
+// size the evidence-bucket counter arrays.
+#define CM_EVIDENCE_BUCKETS (7)
+
// ----------------------------------------------------------------------
//
// Accumulators
@@ -817,6 +822,11 @@ typedef struct _COUNTERS
UINT64 u64BetaCutoffsOnFirstMove;
UINT64 u64CounterMoveTries; // valid counter-move slot existed
UINT64 u64CounterMoveHits; // ...and it was the move that won
+ UINT64 u64LeftoverTries; // leftover (sub-GOOD_MOVE) move tried
+ UINT64 u64LeftoverAlpha; // ...raised alpha (didn't fail high)
+ UINT64 u64LeftoverFH; // ...failed high
+ UINT64 u64CMEvidenceTries[CM_EVIDENCE_BUCKETS];
+ UINT64 u64CMEvidenceFH[CM_EVIDENCE_BUCKETS];
UINT64 u64NullMoves;
UINT64 u64NullMoveSuccess;
#ifdef TEST_NULL
@@ -1072,6 +1082,11 @@ typedef struct _GAME_OPTIONS
UINT64 u64BetaCutoffsOnFirstMove;
UINT64 u64CounterMoveTries;
UINT64 u64CounterMoveHits;
+ UINT64 u64LeftoverTries;
+ UINT64 u64LeftoverAlpha;
+ UINT64 u64LeftoverFH;
+ UINT64 u64CMEvidenceTries[CM_EVIDENCE_BUCKETS];
+ UINT64 u64CMEvidenceFH[CM_EVIDENCE_BUCKETS];
CHAR szLogfile[SMALL_STRING_LEN_CHAR];
CHAR szEGTBPath[SMALL_STRING_LEN_CHAR];
CHAR szBookName[SMALL_STRING_LEN_CHAR];
@@ -1830,6 +1845,46 @@ TestMakeUnmakeMove(void);
#define SECOND_COUNTER_MOVE (0x00800000)
#define STRIP_OFF_FLAGS (0x007FFFFF)
+// Countermove-match tier bonus, placed above GOOD_MOVE (see
+// generate.c's _ScoreAllMoves quiet-move branch) so a *sufficiently
+// evidenced* match (see COUNTERMOVE_EVIDENCE_THRESHOLD) escapes
+// "leftover" classification -- and the fIsLeftoverMove-gated EFP check --
+// entirely, becoming its own tier alongside killers. Conservatively
+// placed below both ply-2 killer slots (FOURTH_KILLER/THIRD_KILLER):
+// the contested-node A/B harness never found clean evidence a
+// qualifying match should outrank killers, only that it beats them on
+// average when forced to compete -- revisit with real data before
+// moving it, don't just nudge it up.
+#define COUNTERMOVE_TIER_BONUS (0x03000000)
+
+// Evidence threshold gating the promotion above -- the same
+// history+continuation sum already used to score ordinary leftovers,
+// evaluated for the specific countermove-matched move. Calibration
+// (search.c's CM_EVIDENCE_BUCKETS harness) showed a match with zero
+// evidence performs identically to an unprivileged leftover (~0.6-
+// 0.85% FH); 10,000 is where the curve first clearly exceeds killer-
+// ply2's own filtered/elite FH% (53.92-64.07% vs. 34.85-51.38%) on all
+// three curated suites, the strongest defensible bar found.
+#define COUNTERMOVE_EVIDENCE_THRESHOLD (10000)
+
+// EXPERIMENT: flee-to-safety same-tier nudge -- a flat bonus added at
+// selection time (movesup.c's SelectBestWithHistory) for a quiet
+// leftover move whose origin square is currently en prise, alongside
+// history/continuation. Unlike the retired GOOD_MOVE-tier promotion,
+// this never changes a move's classification -- it only nudges its
+// rank among other leftovers. Swept empirically via the zero-selection-
+// budget diagnostic, same methodology as CONTINUATION_SCALE.
+#define FLEE_BONUS (100000)
+
+// EXPERIMENT: is history+continuation evidence actually predictive of
+// a countermove match's FH%? Bucket every tried countermove-matched
+// move by its accumulated evidence (g_HistoryCounters[piece][to] +
+// g_ContinuationHistory[prev,cur], the same sum already used to score
+// ordinary leftovers) and track tries/FH per bucket -- see search.c.
+// Independent of tier placement; COUNTERMOVE_TIER_BONUS should be 0
+// while this runs so the calibration reflects unmodified behavior.
+// (CM_EVIDENCE_BUCKETS itself is defined earlier, before COUNTERS.)
+
extern const int g_iQKDeltas[9];
extern const int g_iNDeltas[9];
extern const int g_iBDeltas[5];
@@ -1938,9 +1993,6 @@ InitializeSwapTable(void);
void
InitializeDistanceTable(void);
-ULONG
-NumLeftoverMovesToSelect(SEARCHER_THREAD_CONTEXT *ctx, ULONG uDepth);
-
#ifdef DEBUG
ULONG CheckVectorWithIndex(int i, ULONG uColor);
#define CHECK_VECTOR_WITH_INDEX(i, color) \
@@ -2779,6 +2831,24 @@ TestBitboards(void);
//
extern ULONG g_HistoryCounters[14][128];
+// Continuation history: same growth/decay math as g_HistoryCounters
+// (see dynamic.c), but keyed additionally by the previous move, at the
+// same [piece][to] coarseness -- not full from/to -- to keep the table
+// a manageable size (14*128 * 14*128 = ~3.2M ULONGs, ~12MB). "Did a
+// move of this piece-type to this square tend to fail high right after
+// a move like that?"
+// EXPERIMENT: read-time-only multiplier on the continuation-history
+// contribution to a leftover move's selection score. Write-side growth/
+// decay math is untouched (still self-calibrating by evidence), this
+// just scales how much weight that accumulated evidence carries
+// relative to PSQT+history. Swept empirically via the zero-selection-
+// budget diagnostic binary to trace best-leftover FH% vs. scale.
+#define CONTINUATION_SCALE (1)
+#define CONT_KEY_RANGE (14 * 128)
+#define MOVE_TO_CONT_KEY(mv) (((mv).pMoved * 128) + (mv).cTo)
+#define CONTINUATION_TABLE_SIZE (CONT_KEY_RANGE * CONT_KEY_RANGE)
+extern ULONG g_ContinuationHistory[CONTINUATION_TABLE_SIZE];
+
ULONG
GetMoveFailHighPercentage(MOVE mv, ULONG *puAttempts);