mirror of
https://github.com/sockspls/badfish
synced 2025-07-12 20:19:15 +00:00
Introduce Counter Move History tables
Introduce a counter move history table which additionally is indexed by the last move's piece and target square. For quiet move ordering use now the sum of standard and counter move history table. STC: LLR: 2.96 (-2.94,2.94) [-1.50,4.50] Total: 4747 W: 1005 L: 885 D: 2857 LTC: LLR: 2.95 (-2.94,2.94) [0.00,6.00] Total: 5726 W: 1001 L: 872 D: 3853 Because of reported low NPS on multi core test STC (7 threads): ELO: 7.26 +-3.3 (95%) LOS: 100.0% Total: 14937 W: 2710 L: 2398 D: 9829 Bench: 7725341 Resolves #282
This commit is contained in:
parent
81c7975dcd
commit
13c11f4048
3 changed files with 33 additions and 14 deletions
|
@ -67,8 +67,8 @@ namespace {
|
||||||
/// search captures, promotions and some checks) and how important good move
|
/// search captures, promotions and some checks) and how important good move
|
||||||
/// ordering is at the current node.
|
/// ordering is at the current node.
|
||||||
|
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h,
|
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h, const CounterMovesHistoryStats& cmh,
|
||||||
Move* cm, Move* fm, Search::Stack* s) : pos(p), history(h), depth(d) {
|
Move* cm, Move* fm, Search::Stack* s) : pos(p), history(h), counterMovesHistory(cmh), depth(d) {
|
||||||
|
|
||||||
assert(d > DEPTH_ZERO);
|
assert(d > DEPTH_ZERO);
|
||||||
|
|
||||||
|
@ -87,8 +87,8 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats&
|
||||||
endMoves += (ttMove != MOVE_NONE);
|
endMoves += (ttMove != MOVE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h,
|
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h, const CounterMovesHistoryStats& cmh,
|
||||||
Square s) : pos(p), history(h) {
|
Square s) : pos(p), history(h), counterMovesHistory(cmh) {
|
||||||
|
|
||||||
assert(d <= DEPTH_ZERO);
|
assert(d <= DEPTH_ZERO);
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats&
|
||||||
endMoves += (ttMove != MOVE_NONE);
|
endMoves += (ttMove != MOVE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, PieceType pt)
|
MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, const CounterMovesHistoryStats& cmh, PieceType pt)
|
||||||
: pos(p), history(h) {
|
: pos(p), history(h), counterMovesHistory(cmh) {
|
||||||
|
|
||||||
assert(!pos.checkers());
|
assert(!pos.checkers());
|
||||||
|
|
||||||
|
@ -162,8 +162,13 @@ void MovePicker::score<CAPTURES>() {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void MovePicker::score<QUIETS>() {
|
void MovePicker::score<QUIETS>() {
|
||||||
|
Square prevMoveSq = to_sq((ss-1)->currentMove);
|
||||||
|
Piece prevMovePiece = pos.piece_on(prevMoveSq);
|
||||||
|
const HistoryStats &cmh = counterMovesHistory[prevMovePiece][prevMoveSq];
|
||||||
|
|
||||||
for (auto& m : *this)
|
for (auto& m : *this)
|
||||||
m.value = history[pos.moved_piece(m)][to_sq(m)];
|
m.value = history[pos.moved_piece(m)][to_sq(m)]
|
||||||
|
+ cmh[pos.moved_piece(m)][to_sq(m)];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct Stats {
|
||||||
static const Value Max = Value(250);
|
static const Value Max = Value(250);
|
||||||
|
|
||||||
const T* operator[](Piece pc) const { return table[pc]; }
|
const T* operator[](Piece pc) const { return table[pc]; }
|
||||||
|
T* operator[](Piece pc) { return table[pc]; }
|
||||||
void clear() { std::memset(table, 0, sizeof(table)); }
|
void clear() { std::memset(table, 0, sizeof(table)); }
|
||||||
|
|
||||||
void update(Piece pc, Square to, Move m) {
|
void update(Piece pc, Square to, Move m) {
|
||||||
|
@ -70,6 +71,7 @@ private:
|
||||||
typedef Stats< true, Value> GainsStats;
|
typedef Stats< true, Value> GainsStats;
|
||||||
typedef Stats<false, Value> HistoryStats;
|
typedef Stats<false, Value> HistoryStats;
|
||||||
typedef Stats<false, std::pair<Move, Move> > MovesStats;
|
typedef Stats<false, std::pair<Move, Move> > MovesStats;
|
||||||
|
typedef Stats<false, HistoryStats> CounterMovesHistoryStats;
|
||||||
|
|
||||||
|
|
||||||
/// MovePicker class is used to pick one pseudo legal move at a time from the
|
/// MovePicker class is used to pick one pseudo legal move at a time from the
|
||||||
|
@ -84,9 +86,9 @@ public:
|
||||||
MovePicker(const MovePicker&) = delete;
|
MovePicker(const MovePicker&) = delete;
|
||||||
MovePicker& operator=(const MovePicker&) = delete;
|
MovePicker& operator=(const MovePicker&) = delete;
|
||||||
|
|
||||||
MovePicker(const Position&, Move, Depth, const HistoryStats&, Square);
|
MovePicker(const Position&, Move, Depth, const HistoryStats&, const CounterMovesHistoryStats&, Square);
|
||||||
MovePicker(const Position&, Move, const HistoryStats&, PieceType);
|
MovePicker(const Position&, Move, const HistoryStats&, const CounterMovesHistoryStats&, PieceType);
|
||||||
MovePicker(const Position&, Move, Depth, const HistoryStats&, Move*, Move*, Search::Stack*);
|
MovePicker(const Position&, Move, Depth, const HistoryStats&, const CounterMovesHistoryStats&, Move*, Move*, Search::Stack*);
|
||||||
|
|
||||||
template<bool SpNode> Move next_move();
|
template<bool SpNode> Move next_move();
|
||||||
|
|
||||||
|
@ -98,6 +100,7 @@ private:
|
||||||
|
|
||||||
const Position& pos;
|
const Position& pos;
|
||||||
const HistoryStats& history;
|
const HistoryStats& history;
|
||||||
|
const CounterMovesHistoryStats& counterMovesHistory;
|
||||||
Search::Stack* ss;
|
Search::Stack* ss;
|
||||||
Move* countermoves;
|
Move* countermoves;
|
||||||
Move* followupmoves;
|
Move* followupmoves;
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace {
|
||||||
double BestMoveChanges;
|
double BestMoveChanges;
|
||||||
Value DrawValue[COLOR_NB];
|
Value DrawValue[COLOR_NB];
|
||||||
HistoryStats History;
|
HistoryStats History;
|
||||||
|
CounterMovesHistoryStats CounterMovesHistory;
|
||||||
GainsStats Gains;
|
GainsStats Gains;
|
||||||
MovesStats Countermoves, Followupmoves;
|
MovesStats Countermoves, Followupmoves;
|
||||||
|
|
||||||
|
@ -289,6 +290,7 @@ namespace {
|
||||||
|
|
||||||
TT.new_search();
|
TT.new_search();
|
||||||
History.clear();
|
History.clear();
|
||||||
|
CounterMovesHistory.clear();
|
||||||
Gains.clear();
|
Gains.clear();
|
||||||
Countermoves.clear();
|
Countermoves.clear();
|
||||||
Followupmoves.clear();
|
Followupmoves.clear();
|
||||||
|
@ -687,7 +689,7 @@ namespace {
|
||||||
assert((ss-1)->currentMove != MOVE_NONE);
|
assert((ss-1)->currentMove != MOVE_NONE);
|
||||||
assert((ss-1)->currentMove != MOVE_NULL);
|
assert((ss-1)->currentMove != MOVE_NULL);
|
||||||
|
|
||||||
MovePicker mp(pos, ttMove, History, pos.captured_piece_type());
|
MovePicker mp(pos, ttMove, History, CounterMovesHistory, pos.captured_piece_type());
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
|
|
||||||
while ((move = mp.next_move<false>()) != MOVE_NONE)
|
while ((move = mp.next_move<false>()) != MOVE_NONE)
|
||||||
|
@ -726,7 +728,7 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
Move followupmoves[] = { Followupmoves[pos.piece_on(prevOwnMoveSq)][prevOwnMoveSq].first,
|
Move followupmoves[] = { Followupmoves[pos.piece_on(prevOwnMoveSq)][prevOwnMoveSq].first,
|
||||||
Followupmoves[pos.piece_on(prevOwnMoveSq)][prevOwnMoveSq].second };
|
Followupmoves[pos.piece_on(prevOwnMoveSq)][prevOwnMoveSq].second };
|
||||||
|
|
||||||
MovePicker mp(pos, ttMove, depth, History, countermoves, followupmoves, ss);
|
MovePicker mp(pos, ttMove, depth, History, CounterMovesHistory, countermoves, followupmoves, ss);
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
|
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
|
||||||
improving = ss->staticEval >= (ss-2)->staticEval
|
improving = ss->staticEval >= (ss-2)->staticEval
|
||||||
|
@ -1192,7 +1194,7 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
// to search the moves. Because the depth is <= 0 here, only captures,
|
// to search the moves. Because the depth is <= 0 here, only captures,
|
||||||
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
|
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
|
||||||
// be generated.
|
// be generated.
|
||||||
MovePicker mp(pos, ttMove, depth, History, to_sq((ss-1)->currentMove));
|
MovePicker mp(pos, ttMove, depth, History, CounterMovesHistory, to_sq((ss-1)->currentMove));
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
|
|
||||||
// Loop through the moves until no moves remain or a beta cutoff occurs
|
// Loop through the moves until no moves remain or a beta cutoff occurs
|
||||||
|
@ -1356,7 +1358,16 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
if (is_ok((ss-1)->currentMove))
|
if (is_ok((ss-1)->currentMove))
|
||||||
{
|
{
|
||||||
Square prevMoveSq = to_sq((ss-1)->currentMove);
|
Square prevMoveSq = to_sq((ss-1)->currentMove);
|
||||||
Countermoves.update(pos.piece_on(prevMoveSq), prevMoveSq, move);
|
Piece prevMovePiece = pos.piece_on(prevMoveSq);
|
||||||
|
Countermoves.update(prevMovePiece, prevMoveSq, move);
|
||||||
|
|
||||||
|
HistoryStats& cmh = CounterMovesHistory[prevMovePiece][prevMoveSq];
|
||||||
|
cmh.update(pos.moved_piece(move), to_sq(move), bonus);
|
||||||
|
for (int i = 0; i < quietsCnt; ++i)
|
||||||
|
{
|
||||||
|
Move m = quiets[i];
|
||||||
|
cmh.update(pos.moved_piece(m), to_sq(m), -bonus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_ok((ss-2)->currentMove) && (ss-1)->currentMove == (ss-1)->ttMove)
|
if (is_ok((ss-2)->currentMove) && (ss-1)->currentMove == (ss-1)->ttMove)
|
||||||
|
|
Loading…
Add table
Reference in a new issue