diff --git a/engine/search.cpp b/engine/search.cpp index 4e69f4eb..adfe9533 100644 --- a/engine/search.cpp +++ b/engine/search.cpp @@ -77,6 +77,7 @@ Move killer[2][MAX_PLY]; * TODO: check if overflows are possible */ Value history[2][64][64]; +Value capthist[6][6][64]; // [piece][captured piece][dst] /** * The counter-move heuristic is a move ordering heuristic that helps sort moves that @@ -94,6 +95,11 @@ void update_history(bool side, Square from, Square to, Value bonus) { history[side][from][to] += cbonus - history[side][from][to] * abs(bonus) / MAX_HISTORY; } +void update_capthist(PieceType piece, PieceType captured, Square dst, Value bonus) { + int cbonus = std::clamp(bonus, (Value)(-MAX_HISTORY), MAX_HISTORY); + capthist[piece][captured][dst] += cbonus - capthist[piece][captured][dst] * abs(bonus) / MAX_HISTORY; +} + /** * Perform the quiescence search * @@ -207,7 +213,8 @@ pzstd::vector> order_moves(Board &board, pzstd::vector quiets; + pzstd::vector quiets, captures; for (int i = 0; i < moves.size(); i++) { Move &move = scores[i].first; @@ -406,6 +413,12 @@ Value __recurse(Board &board, int depth, Value alpha = -VALUE_INFINITE, Value be update_history(board.side, qmove.src(), qmove.dst(), -bonus); // Penalize quiet moves } cmh[board.side][line[ply-1].src()][line[ply-1].dst()] = move; // Update counter-move history + } else { + const Value bonus = depth * depth; + update_capthist(PieceType(board.mailbox[move.src()] & 7), PieceType(board.mailbox[move.dst()] & 7), move.dst(), bonus); + for (auto &cmove : captures) { + update_capthist(PieceType(board.mailbox[cmove.src()] & 7), PieceType(board.mailbox[cmove.dst()] & 7), cmove.dst(), -bonus); + } } return best; } @@ -414,6 +427,7 @@ Value __recurse(Board &board, int depth, Value alpha = -VALUE_INFINITE, Value be break; if (!capt && !promo) quiets.push_back(move); + else if (capt) captures.push_back(move); } // Stalemate detection