diff --git a/src/Makefile b/src/Makefile
index 4307b7c7473..e7f8ce556bb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -57,7 +57,7 @@ SRCS = benchmark.cpp bitboard.cpp evaluate.cpp main.cpp \
search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \
nnue/nnue_misc.cpp nnue/features/half_ka_v2_hm.cpp nnue/network.cpp engine.cpp score.cpp memory.cpp
-HEADERS = benchmark.h bitboard.h evaluate.h misc.h movegen.h movepick.h \
+HEADERS = benchmark.h bitboard.h evaluate.h misc.h movegen.h movepick.h history.h \
nnue/nnue_misc.h nnue/features/half_ka_v2_hm.h nnue/layers/affine_transform.h \
nnue/layers/affine_transform_sparse_input.h nnue/layers/clipped_relu.h nnue/layers/simd.h \
nnue/layers/sqr_clipped_relu.h nnue/nnue_accumulator.h nnue/nnue_architecture.h \
diff --git a/src/history.h b/src/history.h
new file mode 100644
index 00000000000..8d14a7a7cb1
--- /dev/null
+++ b/src/history.h
@@ -0,0 +1,185 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2024 The Stockfish developers (see AUTHORS file)
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef HISTORY_H_INCLUDED
+#define HISTORY_H_INCLUDED
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include // IWYU pragma: keep
+
+#include "position.h"
+
+namespace Stockfish {
+
+constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2
+constexpr int CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2
+constexpr int CORRECTION_HISTORY_LIMIT = 1024;
+constexpr int LOW_PLY_HISTORY_SIZE = 4;
+
+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,
+ "CORRECTION_HISTORY_SIZE has to be a power of 2");
+
+enum PawnHistoryType {
+ Normal,
+ Correction
+};
+
+template
+inline int pawn_structure_index(const Position& pos) {
+ return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1);
+}
+
+inline int major_piece_index(const Position& pos) {
+ return pos.major_piece_key() & (CORRECTION_HISTORY_SIZE - 1);
+}
+
+inline int minor_piece_index(const Position& pos) {
+ return pos.minor_piece_key() & (CORRECTION_HISTORY_SIZE - 1);
+}
+
+template
+inline int non_pawn_index(const Position& pos) {
+ return pos.non_pawn_key(c) & (CORRECTION_HISTORY_SIZE - 1);
+}
+
+// StatsEntry stores the stat table value. It is usually a number but could
+// be a move or even a nested history. We use a class instead of a naked value
+// to directly call history update operator<<() on the entry so to use stats
+// tables at caller sites as simple multi-dim arrays.
+template
+class StatsEntry {
+
+ T entry;
+
+ public:
+ void operator=(const T& v) { entry = v; }
+ T* operator&() { return &entry; }
+ T* operator->() { return &entry; }
+ operator const T&() const { return entry; }
+
+ void operator<<(int bonus) {
+ static_assert(D <= std::numeric_limits::max(), "D overflows T");
+
+ // Make sure that bonus is in range [-D, D]
+ int clampedBonus = std::clamp(bonus, -D, D);
+ entry += clampedBonus - entry * std::abs(clampedBonus) / D;
+
+ assert(std::abs(entry) <= D);
+ }
+};
+
+// Stats is a generic N-dimensional array used to store various statistics.
+// The first template parameter T is the base type of the array, and the second
+// template parameter D limits the range of updates in [-D, D] when we update
+// values with the << operator, while the last parameters (Size and Sizes)
+// encode the dimensions of the array.
+template
+struct Stats: public std::array, Size> {
+ using stats = Stats;
+
+ void fill(const T& v) {
+
+ // For standard-layout 'this' points to the first struct member
+ assert(std::is_standard_layout_v);
+
+ using entry = StatsEntry;
+ entry* p = reinterpret_cast(this);
+ std::fill(p, p + sizeof(*this) / sizeof(entry), v);
+ }
+};
+
+template
+struct Stats: public std::array, Size> {};
+
+// In stats table, D=0 means that the template parameter is not used
+enum StatsParams {
+ NOT_USED = 0
+};
+enum StatsType {
+ NoCaptures,
+ Captures
+};
+
+// ButterflyHistory records how often quiet moves have been successful or unsuccessful
+// during the current search, and is used for reduction and move ordering decisions.
+// It uses 2 tables (one for each color) indexed by the move's from and to squares,
+// see https://www.chessprogramming.org/Butterfly_Boards (~11 elo)
+using ButterflyHistory = Stats;
+
+// LowPlyHistory is adressed by play and move's from and to squares, used
+// to improve move ordering near the root
+using LowPlyHistory = Stats;
+
+// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
+using CapturePieceToHistory = Stats;
+
+// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
+using PieceToHistory = Stats;
+
+// ContinuationHistory is the combined history of a given pair of moves, usually
+// the current one given a previous one. The nested history table is based on
+// PieceToHistory instead of ButterflyBoards.
+// (~63 elo)
+using ContinuationHistory = Stats;
+
+// PawnHistory is addressed by the pawn structure and a move's [piece][to]
+using PawnHistory = Stats;
+
+// 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.
+// see https://www.chessprogramming.org/Static_Evaluation_Correction_History
+enum CorrHistType {
+ Pawn, // By color and pawn structure
+ Major, // By color and positions of major pieces (Queen, Rook) and King
+ Minor, // By color and positions of minor pieces (Knight, Bishop) and King
+ NonPawn, // By color and non-pawn material positions
+ PieceTo, // By [piece][to] move
+ Continuation, // Combined history of move pairs
+};
+
+template
+struct CorrHistTypedef {
+ using type = Stats;
+};
+
+template<>
+struct CorrHistTypedef {
+ using type = Stats;
+};
+
+template<>
+struct CorrHistTypedef {
+ using type = Stats::type, NOT_USED, PIECE_NB, SQUARE_NB>;
+};
+
+template
+using CorrectionHistory = typename CorrHistTypedef::type;
+
+} // namespace Stockfish
+
+#endif // #ifndef HISTORY_H_INCLUDED
diff --git a/src/movepick.cpp b/src/movepick.cpp
index 2a1fb837348..720f2e031ea 100644
--- a/src/movepick.cpp
+++ b/src/movepick.cpp
@@ -19,7 +19,9 @@
#include "movepick.h"
#include
+#include
#include
+#include
#include
#include "bitboard.h"
diff --git a/src/movepick.h b/src/movepick.h
index f8f84d02474..0278b70ec82 100644
--- a/src/movepick.h
+++ b/src/movepick.h
@@ -19,172 +19,13 @@
#ifndef MOVEPICK_H_INCLUDED
#define MOVEPICK_H_INCLUDED
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include // IWYU pragma: keep
-
+#include "history.h"
#include "movegen.h"
-#include "position.h"
#include "types.h"
namespace Stockfish {
-constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2
-constexpr int CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2
-constexpr int CORRECTION_HISTORY_LIMIT = 1024;
-constexpr int LOW_PLY_HISTORY_SIZE = 4;
-
-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,
- "CORRECTION_HISTORY_SIZE has to be a power of 2");
-
-enum PawnHistoryType {
- Normal,
- Correction
-};
-
-template
-inline int pawn_structure_index(const Position& pos) {
- return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1);
-}
-
-inline int material_index(const Position& pos) {
- return pos.material_key() & (CORRECTION_HISTORY_SIZE - 1);
-}
-
-inline int major_piece_index(const Position& pos) {
- return pos.major_piece_key() & (CORRECTION_HISTORY_SIZE - 1);
-}
-
-inline int minor_piece_index(const Position& pos) {
- return pos.minor_piece_key() & (CORRECTION_HISTORY_SIZE - 1);
-}
-
-template
-inline int non_pawn_index(const Position& pos) {
- return pos.non_pawn_key(c) & (CORRECTION_HISTORY_SIZE - 1);
-}
-
-// StatsEntry stores the stat table value. It is usually a number but could
-// be a move or even a nested history. We use a class instead of a naked value
-// to directly call history update operator<<() on the entry so to use stats
-// tables at caller sites as simple multi-dim arrays.
-template
-class StatsEntry {
-
- T entry;
-
- public:
- void operator=(const T& v) { entry = v; }
- T* operator&() { return &entry; }
- T* operator->() { return &entry; }
- operator const T&() const { return entry; }
-
- void operator<<(int bonus) {
- static_assert(D <= std::numeric_limits::max(), "D overflows T");
-
- // Make sure that bonus is in range [-D, D]
- int clampedBonus = std::clamp(bonus, -D, D);
- entry += clampedBonus - entry * std::abs(clampedBonus) / D;
-
- assert(std::abs(entry) <= D);
- }
-};
-
-// Stats is a generic N-dimensional array used to store various statistics.
-// The first template parameter T is the base type of the array, and the second
-// template parameter D limits the range of updates in [-D, D] when we update
-// values with the << operator, while the last parameters (Size and Sizes)
-// encode the dimensions of the array.
-template
-struct Stats: public std::array, Size> {
- using stats = Stats;
-
- void fill(const T& v) {
-
- // For standard-layout 'this' points to the first struct member
- assert(std::is_standard_layout_v);
-
- using entry = StatsEntry;
- entry* p = reinterpret_cast(this);
- std::fill(p, p + sizeof(*this) / sizeof(entry), v);
- }
-};
-
-template
-struct Stats: public std::array, Size> {};
-
-// In stats table, D=0 means that the template parameter is not used
-enum StatsParams {
- NOT_USED = 0
-};
-enum StatsType {
- NoCaptures,
- Captures
-};
-
-// ButterflyHistory records how often quiet moves have been successful or unsuccessful
-// during the current search, and is used for reduction and move ordering decisions.
-// It uses 2 tables (one for each color) indexed by the move's from and to squares,
-// see https://www.chessprogramming.org/Butterfly_Boards (~11 elo)
-using ButterflyHistory = Stats;
-
-// LowPlyHistory is adressed by play and move's from and to squares, used
-// to improve move ordering near the root
-using LowPlyHistory = Stats;
-
-// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
-using CapturePieceToHistory = Stats;
-
-// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
-using PieceToHistory = Stats;
-
-// ContinuationHistory is the combined history of a given pair of moves, usually
-// the current one given a previous one. The nested history table is based on
-// PieceToHistory instead of ButterflyBoards.
-// (~63 elo)
-using ContinuationHistory = Stats;
-
-// PawnHistory is addressed by the pawn structure and a move's [piece][to]
-using PawnHistory = Stats;
-
-// 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.
-// see https://www.chessprogramming.org/Static_Evaluation_Correction_History
-enum CorrHistType {
- Pawn, // By color and pawn structure
- Major, // By color and positions of major pieces (Queen, Rook) and King
- Minor, // By color and positions of minor pieces (Knight, Bishop) and King
- NonPawn, // By color and non-pawn material positions
- PieceTo, // By [piece][to] move
- Continuation, // Combined history of move pairs
-};
-
-template
-struct CorrHistTypedef {
- using type = Stats;
-};
-
-template<>
-struct CorrHistTypedef {
- using type = Stats;
-};
-
-template<>
-struct CorrHistTypedef {
- using type = Stats::type, NOT_USED, PIECE_NB, SQUARE_NB>;
-};
-
-template
-using CorrectionHistory = typename CorrHistTypedef::type;
+class Position;
// 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
diff --git a/src/search.cpp b/src/search.cpp
index 4864057c1b1..d6914da0b67 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -34,6 +34,7 @@
#include
#include "evaluate.h"
+#include "history.h"
#include "misc.h"
#include "movegen.h"
#include "movepick.h"
diff --git a/src/search.h b/src/search.h
index 751a398483f..b618855b9fc 100644
--- a/src/search.h
+++ b/src/search.h
@@ -31,8 +31,8 @@
#include
#include
+#include "history.h"
#include "misc.h"
-#include "movepick.h"
#include "nnue/network.h"
#include "nnue/nnue_accumulator.h"
#include "numa.h"