Counter-Move History Continuity (CMHC)

Currently, the engine updates each level of the continuation history stack (ply -1, -2, -3, etc.) with fixed weights that are independent of one another. The idea behind CMHC is to scale the magnitude of these updates based on the consistency of the move's performance across the stack.
By tracking how often a move has historically performed well (positive history) within the current continuation context, we can adjust the update magnitude dynamically. Moves that demonstrate "continuity" (appearing as strong candidates across multiple historical contexts) receive more significant updates, while unproven or inconsistent moves are dampened.

Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 103264 W: 26954 L: 26541 D: 49769
Ptnml(0-2): 338, 11910, 26728, 12313, 343
https://tests.stockfishchess.org/tests/view/69a81702fac54339cf435a87

Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 47406 W: 12259 L: 11920 D: 23227
Ptnml(0-2): 22, 5052, 13237, 5349, 43
https://tests.stockfishchess.org/tests/view/69aab480bd35724e4b290498

closes https://github.com/official-stockfish/Stockfish/pull/6653

Bench: 2356418

Co-Authored-By: Daniel Samek <samekdaniel@email.cz>
This commit is contained in:
FauziAkram
2026-03-07 22:16:22 +01:00
committed by Joost VandeVondele
co-authored by Daniel Samek
parent 868b63d421
commit 8b6d8def30
+12 -1
View File
@@ -1873,6 +1873,10 @@ void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) {
static constexpr std::array<ConthistBonus, 6> conthist_bonuses = { static constexpr std::array<ConthistBonus, 6> conthist_bonuses = {
{{1, 1106}, {2, 705}, {3, 316}, {4, 572}, {5, 126}, {6, 427}}}; {{1, 1106}, {2, 705}, {3, 316}, {4, 572}, {5, 126}, {6, 427}}};
// Multipliers for positive history consistency
constexpr int CMHCMultipliers[] = {87, 94, 106, 118, 114, 128, 128};
int positiveCount = 0;
for (const auto [i, weight] : conthist_bonuses) for (const auto [i, weight] : conthist_bonuses)
{ {
// Only update the first 2 continuation histories if we are in check // Only update the first 2 continuation histories if we are in check
@@ -1880,7 +1884,14 @@ void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) {
break; break;
if (((ss - i)->currentMove).is_ok()) if (((ss - i)->currentMove).is_ok())
(*(ss - i)->continuationHistory)[pc][to] << (bonus * weight / 1024) + 82 * (i < 2); {
auto& historyEntry = (*(ss - i)->continuationHistory)[pc][to];
if (historyEntry > 0)
positiveCount++;
int multiplier = CMHCMultipliers[positiveCount];
historyEntry << (bonus * weight * multiplier / 131072) + 82 * (i < 2);
}
} }
} }