Introduce capture history table for capture move sorting

Introduce capture move history table indexed by moved piece,
target square and captured piece type for sorting capture moves.

STC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 11374 W: 2096 L: 1924 D: 7354
http://tests.stockfishchess.org/tests/view/59fac8dc0ebc590ccbb89fc5

LTC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 24791 W: 3196 L: 3001 D: 18594
http://tests.stockfishchess.org/tests/view/59fae4d20ebc590ccbb89fd9

Bench: 5536775
This commit is contained in:
Stefan Geschwentner
2017-11-03 13:57:18 +01:00
committed by Marco Costalba
parent 486c8175c4
commit 4bc11984fc
5 changed files with 79 additions and 17 deletions
+33 -6
View File
@@ -109,6 +109,7 @@ namespace {
void update_pv(Move* pv, Move move, Move* childPv);
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
bool pv_is_draw(Position& pos);
// perft() is our utility to verify move generation. All the leaf nodes up
@@ -500,7 +501,7 @@ namespace {
assert(!(PvNode && cutNode));
assert(depth / ONE_PLY * ONE_PLY == depth);
Move pv[MAX_PLY+1], quietsSearched[64];
Move pv[MAX_PLY+1], capturesSearched[32], quietsSearched[64];
StateInfo st;
TTEntry* tte;
Key posKey;
@@ -510,12 +511,12 @@ namespace {
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact;
Piece movedPiece;
int moveCount, quietCount;
int moveCount, captureCount, quietCount;
// Step 1. Initialize node
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
moveCount = quietCount = ss->moveCount = 0;
moveCount = captureCount = quietCount = ss->moveCount = 0;
ss->statScore = 0;
bestValue = -VALUE_INFINITE;
@@ -579,6 +580,8 @@ namespace {
{
if (!pos.capture_or_promotion(ttMove))
update_stats(pos, ss, ttMove, nullptr, 0, stat_bonus(depth));
else
update_capture_stats(pos, ttMove, nullptr, 0, stat_bonus(depth));
// Extra penalty for a quiet TT move in previous ply when it gets refuted
if ((ss-1)->moveCount == 1 && !pos.captured_piece())
@@ -729,7 +732,7 @@ namespace {
assert(is_ok((ss-1)->currentMove));
MovePicker mp(pos, ttMove, rbeta - ss->staticEval);
MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
while ((move = mp.next_move()) != MOVE_NONE)
if (pos.legal(move))
@@ -763,7 +766,7 @@ moves_loop: // When in check search starts from here
const PieceToHistory* contHist[] = { (ss-1)->contHistory, (ss-2)->contHistory, nullptr, (ss-4)->contHistory };
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, contHist, countermove, ss->killers);
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, &thisThread->captureHistory, contHist, countermove, ss->killers);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
improving = ss->staticEval >= (ss-2)->staticEval
/* || ss->staticEval == VALUE_NONE Already implicit in the previous condition */
@@ -1054,6 +1057,8 @@ moves_loop: // When in check search starts from here
if (!captureOrPromotion && move != bestMove && quietCount < 64)
quietsSearched[quietCount++] = move;
else if (captureOrPromotion && move != bestMove && captureCount < 32)
capturesSearched[captureCount++] = move;
}
// The following condition would detect a stop only after move loop has been
@@ -1079,6 +1084,8 @@ moves_loop: // When in check search starts from here
// Quiet best move: update move sorting heuristics
if (!pos.capture_or_promotion(bestMove))
update_stats(pos, ss, bestMove, quietsSearched, quietCount, stat_bonus(depth));
else
update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth));
// Extra penalty for a quiet TT move in previous ply when it gets refuted
if ((ss-1)->moveCount == 1 && !pos.captured_piece())
@@ -1207,7 +1214,7 @@ moves_loop: // When in check search starts from here
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
// be generated.
MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory, to_sq((ss-1)->currentMove));
MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory, &pos.this_thread()->captureHistory, to_sq((ss-1)->currentMove));
// Loop through the moves until no moves remain or a beta cutoff occurs
while ((move = mp.next_move()) != MOVE_NONE)
@@ -1362,6 +1369,26 @@ moves_loop: // When in check search starts from here
}
// update_capture_stats() updates move sorting heuristics when a new capture best move is found
void update_capture_stats(const Position& pos, Move move,
Move* captures, int captureCnt, int bonus) {
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
Piece moved_piece = pos.moved_piece(move);
PieceType captured = type_of(pos.piece_on(to_sq(move)));
captureHistory.update(moved_piece,to_sq(move), captured, bonus);
// Decrease all the other played capture moves
for (int i = 0; i < captureCnt; ++i)
{
moved_piece = pos.moved_piece(captures[i]);
captured = type_of(pos.piece_on(to_sq(captures[i])));
captureHistory.update(moved_piece, to_sq(captures[i]), captured, -bonus);
}
}
// update_stats() updates move sorting heuristics when a new quiet best move is found
void update_stats(const Position& pos, Stack* ss, Move move,