@@ -82,6 +82,7 @@ namespace {
8282 double BestMoveChanges;
8383 Value DrawValue[COLOR_NB];
8484 HistoryStats History;
85+ GainsStats Gains;
8586 CountermovesStats Countermoves;
8687
8788 template <NodeType NT>
@@ -293,6 +294,7 @@ namespace {
293294 Value bestValue, alpha, beta, delta;
294295
295296 std::memset (ss-2 , 0 , 5 * sizeof (Stack));
297+ (ss-1 )->currentMove = MOVE_NULL; // Hack to skip update gains
296298
297299 depth = 0 ;
298300 BestMoveChanges = 0 ;
@@ -301,6 +303,7 @@ namespace {
301303
302304 TT.new_search ();
303305 History.clear ();
306+ Gains.clear ();
304307 Countermoves.clear ();
305308
306309 PVSize = Options[" MultiPV" ];
@@ -487,9 +490,8 @@ namespace {
487490 SplitPoint* splitPoint;
488491 Key posKey;
489492 Move ttMove, move, excludedMove, bestMove, threatMove;
490- Depth ext, newDepth;
491- Value bestValue, value, ttValue;
492- Value eval, nullValue;
493+ Depth ext, newDepth, predictedDepth;
494+ Value bestValue, value, ttValue, eval, nullValue, futilityValue;
493495 bool inCheck, givesCheck, pvMove, singularExtensionNode, improving;
494496 bool captureOrPromotion, dangerous, doFullDepthSearch;
495497 int moveCount, quietCount;
@@ -601,6 +603,16 @@ namespace {
601603 TT.store (posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, ss->staticEval );
602604 }
603605
606+ if ( !pos.captured_piece_type ()
607+ && ss->staticEval != VALUE_NONE
608+ && (ss-1 )->staticEval != VALUE_NONE
609+ && (move = (ss-1 )->currentMove ) != MOVE_NULL
610+ && type_of (move) == NORMAL)
611+ {
612+ Square to = to_sq (move);
613+ Gains.update (pos.piece_on (to), to, -(ss-1 )->staticEval - ss->staticEval );
614+ }
615+
604616 // Step 6. Razoring (skipped when in check)
605617 if ( !PvNode
606618 && depth < 4 * ONE_PLY
@@ -847,12 +859,13 @@ namespace {
847859 continue ;
848860 }
849861
850- Depth predictedDepth = newDepth - reduction<PvNode>(improving, depth, moveCount);
862+ predictedDepth = newDepth - reduction<PvNode>(improving, depth, moveCount);
851863
852864 // Futility pruning: parent node
853865 if (predictedDepth < 7 * ONE_PLY)
854866 {
855- Value futilityValue = ss->staticEval + futility_margin (predictedDepth) + Value (128 );
867+ futilityValue = ss->staticEval + futility_margin (predictedDepth)
868+ + Value (128 ) + Gains[pos.moved_piece (move)][to_sq (move)];
856869
857870 if (futilityValue <= alpha)
858871 {
@@ -869,8 +882,7 @@ namespace {
869882 }
870883
871884 // Prune moves with negative SEE at low depths
872- if ( predictedDepth < 4 * ONE_PLY
873- && pos.see_sign (move) < 0 )
885+ if (predictedDepth < 4 * ONE_PLY && pos.see_sign (move) < 0 )
874886 {
875887 if (SpNode)
876888 splitPoint->mutex .lock ();
@@ -883,7 +895,7 @@ namespace {
883895 // Check for legality only before to do the move
884896 if (!RootNode && !SpNode && !pos.legal (move, ci.pinned ))
885897 {
886- --moveCount ;
898+ moveCount-- ;
887899 continue ;
888900 }
889901
0 commit comments