- Value hValue = thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)];
- Value cmhValue = cmh[pos.piece_on(to_sq(move))][to_sq(move)];
-
- const CounterMoveStats* fm = (ss - 2)->counterMoves;
- const CounterMoveStats* fm2 = (ss - 4)->counterMoves;
- Value fmValue = (fm ? (*fm)[pos.piece_on(to_sq(move))][to_sq(move)] : VALUE_ZERO);
- Value fm2Value = (fm2 ? (*fm2)[pos.piece_on(to_sq(move))][to_sq(move)] : VALUE_ZERO);
-
- // Increase reduction for cut nodes and moves with a bad history
- if ( (!PvNode && cutNode)
- || (hValue < VALUE_ZERO && cmhValue <= VALUE_ZERO))
- r += ONE_PLY;
-
- // Decrease/increase reduction for moves with a good/bad history
- int rHist = (hValue + cmhValue + fmValue + fm2Value) / 20000;
- r = std::max(DEPTH_ZERO, r - rHist * ONE_PLY);
-
- // Decrease reduction for moves that escape a capture. Filter out
- // castling moves, because they are coded as "king captures rook" and
- // hence break make_move(). Also use see() instead of see_sign(),
- // because the destination square is empty.
- if ( r
- && type_of(move) == NORMAL
- && type_of(pos.piece_on(to_sq(move))) != PAWN
- && pos.see(make_move(to_sq(move), from_sq(move))) < VALUE_ZERO)
- r = std::max(DEPTH_ZERO, r - ONE_PLY);
+
+ if (captureOrPromotion)
+ r -= r ? ONE_PLY : DEPTH_ZERO;
+ else
+ {
+ // Increase reduction for cut nodes
+ if (cutNode)
+ r += 2 * ONE_PLY;
+
+ // Decrease reduction for moves that escape a capture. Filter out
+ // castling moves, because they are coded as "king captures rook" and
+ // hence break make_move(). Also use see() instead of see_sign(),
+ // because the destination square is empty.
+ else if ( type_of(move) == NORMAL
+ && type_of(pos.piece_on(to_sq(move))) != PAWN
+ && !pos.see_ge(make_move(to_sq(move), from_sq(move)), VALUE_ZERO))
+ r -= 2 * ONE_PLY;
+
+ ss->history = thisThread->history[moved_piece][to_sq(move)]
+ + (cmh ? (*cmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
+ + (fmh ? (*fmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
+ + (fmh2 ? (*fmh2)[moved_piece][to_sq(move)] : VALUE_ZERO)
+ + thisThread->fromTo.get(~pos.side_to_move(), move)
+ - 8000; // Correction factor
+
+ // Decrease/increase reduction by comparing opponent's stat score
+ if (ss->history > VALUE_ZERO && (ss-1)->history < VALUE_ZERO)
+ r -= ONE_PLY;
+
+ else if (ss->history < VALUE_ZERO && (ss-1)->history > VALUE_ZERO)
+ r += ONE_PLY;
+
+ // Decrease/increase reduction for moves with a good/bad history
+ r = std::max(DEPTH_ZERO, (r / ONE_PLY - ss->history / 20000) * ONE_PLY);
+ }