+ // update_all_stats() updates stats at the end of search() when a bestMove is found
+
+ void update_all_stats(const Position& pos, Stack* ss, Move bestMove, Value bestValue, Value beta, Square prevSq,
+ Move* quietsSearched, int quietCount, Move* capturesSearched, int captureCount, Depth depth, bool pastPV) {
+
+ int bonus1, bonus2;
+ Color us = pos.side_to_move();
+ Thread* thisThread = pos.this_thread();
+ CapturePieceToHistory& captureHistory = thisThread->captureHistory;
+ Piece moved_piece = pos.moved_piece(bestMove);
+ PieceType captured = type_of(pos.piece_on(to_sq(bestMove)));
+
+ bonus1 = stat_bonus(depth + 1);
+ bonus2 = pastPV || bestValue > beta + PawnValueMg ? bonus1 // larger bonus
+ : stat_bonus(depth); // smaller bonus
+
+ if (!pos.capture_or_promotion(bestMove))
+ {
+ update_quiet_stats(pos, ss, bestMove, bonus2);
+
+ // Decrease all the non-best quiet moves
+ for (int i = 0; i < quietCount; ++i)
+ {
+ thisThread->mainHistory[us][from_to(quietsSearched[i])] << -bonus2;
+ update_continuation_histories(ss, pos.moved_piece(quietsSearched[i]), to_sq(quietsSearched[i]), -bonus2);
+ }
+ }
+ else
+ captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1;
+
+ // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
+ if ( ((ss-1)->moveCount == 1 || ((ss-1)->currentMove == (ss-1)->killers[0]))
+ && !pos.captured_piece())
+ update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1);
+
+ // Decrease all the non-best capture moves
+ for (int i = 0; i < captureCount; ++i)
+ {
+ moved_piece = pos.moved_piece(capturesSearched[i]);
+ captured = type_of(pos.piece_on(to_sq(capturesSearched[i])));
+ captureHistory[moved_piece][to_sq(capturesSearched[i])][captured] << -bonus1;
+ }
+ }
+
+