1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-29 16:23:09 +00:00

Introduce Material Correction History

Idea from Caissa (https://github.com/Witek902/Caissa) chess engine.

Add a secondary correction history indexed by the material key of a position.
The material key is the zobrist hash representing the number of pieces left in a
position.

Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 189472 W: 49360 L: 48813 D: 91299
Ptnml(0-2): 666, 22453, 47953, 22996, 668
https://tests.stockfishchess.org/tests/view/66cbddafbf8c9d8780fda9f1

Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 224190 W: 57022 L: 56312 D: 110856
Ptnml(0-2): 197, 24723, 61540, 25443, 192
https://tests.stockfishchess.org/tests/view/66cd529bbf8c9d8780fdab4c

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

Bench: 1462697
This commit is contained in:
Shawn Xu 2024-08-23 17:13:49 -07:00 committed by Disservin
parent 4fb04eb3df
commit ddc9f48bc3
3 changed files with 36 additions and 16 deletions

View file

@ -34,14 +34,15 @@
namespace Stockfish {
constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2
constexpr int CORRECTION_HISTORY_SIZE = 16384; // has to be a power of 2
constexpr int CORRECTION_HISTORY_LIMIT = 1024;
constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2
constexpr int PAWN_CORRECTION_HISTORY_SIZE = 16384; // has to be a power of 2
constexpr int MATERIAL_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2
constexpr int CORRECTION_HISTORY_LIMIT = 1024;
static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0,
"PAWN_HISTORY_SIZE has to be a power of 2");
static_assert((CORRECTION_HISTORY_SIZE & (CORRECTION_HISTORY_SIZE - 1)) == 0,
static_assert((PAWN_CORRECTION_HISTORY_SIZE & (PAWN_CORRECTION_HISTORY_SIZE - 1)) == 0,
"CORRECTION_HISTORY_SIZE has to be a power of 2");
enum PawnHistoryType {
@ -51,7 +52,11 @@ enum PawnHistoryType {
template<PawnHistoryType T = Normal>
inline int pawn_structure_index(const Position& pos) {
return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1);
return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : PAWN_CORRECTION_HISTORY_SIZE) - 1);
}
inline int material_index(const Position& pos) {
return pos.material_key() & (MATERIAL_CORRECTION_HISTORY_SIZE - 1);
}
// StatsEntry stores the stat table value. It is usually a number but could
@ -133,9 +138,18 @@ using ContinuationHistory = Stats<PieceToHistory, NOT_USED, PIECE_NB, SQUARE_NB>
// PawnHistory is addressed by the pawn structure and a move's [piece][to]
using PawnHistory = Stats<int16_t, 8192, PAWN_HISTORY_SIZE, PIECE_NB, SQUARE_NB>;
// CorrectionHistory is addressed by color and pawn structure
using CorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
// Correction histories record differences between the static evaluation of
// positions and their search score. It is used to improve the static evaluation
// used by some search heuristics.
// PawnCorrectionHistory is addressed by color and pawn structure
using PawnCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, PAWN_CORRECTION_HISTORY_SIZE>;
// MaterialCorrectionHistory is addressed by color and material configuration
using MaterialCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, MATERIAL_CORRECTION_HISTORY_SIZE>;
// The MovePicker class is used to pick one pseudo-legal move at a time from the
// current position. The most important method is next_move(), which emits one

View file

@ -81,7 +81,10 @@ constexpr int futility_move_count(bool improving, Depth depth) {
// Add correctionHistory value to raw staticEval and guarantee evaluation
// does not hit the tablebase range.
Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) {
auto cv = w.correctionHistory[pos.side_to_move()][pawn_structure_index<Correction>(pos)];
const auto pcv =
w.pawnCorrectionHistory[pos.side_to_move()][pawn_structure_index<Correction>(pos)];
const auto mcv = w.materialCorrectionHistory[pos.side_to_move()][material_index(pos)];
const auto cv = (2 * pcv + mcv) / 3;
v += 66 * cv / 512;
return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
}
@ -487,7 +490,8 @@ void Search::Worker::clear() {
mainHistory.fill(0);
captureHistory.fill(-700);
pawnHistory.fill(-1188);
correctionHistory.fill(0);
pawnCorrectionHistory.fill(0);
materialCorrectionHistory.fill(0);
for (bool inCheck : {false, true})
for (StatsType c : {NoCaptures, Captures})
@ -1390,7 +1394,8 @@ moves_loop: // When in check, search starts here
{
auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8,
-CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4);
thisThread->correctionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
thisThread->pawnCorrectionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
thisThread->materialCorrectionHistory[us][material_index(pos)] << bonus;
}
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);

View file

@ -277,11 +277,12 @@ class Worker {
void ensure_network_replicated();
// Public because they need to be updatable by the stats
ButterflyHistory mainHistory;
CapturePieceToHistory captureHistory;
ContinuationHistory continuationHistory[2][2];
PawnHistory pawnHistory;
CorrectionHistory correctionHistory;
ButterflyHistory mainHistory;
CapturePieceToHistory captureHistory;
ContinuationHistory continuationHistory[2][2];
PawnHistory pawnHistory;
PawnCorrectionHistory pawnCorrectionHistory;
MaterialCorrectionHistory materialCorrectionHistory;
private:
void iterative_deepening();