+ if (excValue < ttValue - SingleReplyMargin)
+ ext = OnePly;
+ }
+ }
+
+ newDepth = depth - OnePly + ext;
+
+ // Update current move
+ movesSearched[moveCount++] = ss[ply].currentMove = move;
+
+ // Futility pruning for captures
+ // FIXME: test disabling 'Futility pruning for captures'
+ // FIXME: test with 'newDepth < RazorDepth'
+ Color them = opposite_color(pos.side_to_move());
+
+ if ( !isCheck
+ && newDepth < SelectiveDepth
+ && !dangerous
+ && pos.move_is_capture(move)
+ && !pos.move_is_check(move, ci)
+ && !move_is_promotion(move)
+ && move != ttMove
+ && !move_is_ep(move)
+ && (pos.type_of_piece_on(move_to(move)) != PAWN || !pos.pawn_is_passed(them, move_to(move)))) // Do not prune passed pawn captures
+ {
+ int preFutilityValueMargin = 0;
+
+ if (newDepth >= OnePly)
+ preFutilityValueMargin = 112 * bitScanReverse32(int(newDepth) * int(newDepth) / 2);
+
+ Value futilityCaptureValue = ss[ply].eval + pos.endgame_value_of_piece_on(move_to(move)) + preFutilityValueMargin + ei.futilityMargin + 90;
+
+ if (futilityCaptureValue < beta)
+ {
+ if (futilityCaptureValue > bestValue)
+ bestValue = futilityCaptureValue;
+ continue;
+ }
+ }
+
+ // Futility pruning
+ if ( !isCheck
+ && !dangerous
+ && !captureOrPromotion
+ && !move_is_castle(move)
+ && move != ttMove)
+ {
+ // Move count based pruning
+ if ( moveCount >= FutilityMoveCountMargin
+ && ok_to_prune(pos, move, ss[ply].threatMove)
+ && bestValue > value_mated_in(PLY_MAX))
+ continue;
+
+ // Value based pruning
+ Depth predictedDepth = newDepth;
+
+ //FIXME HACK: awful code duplication
+ double red = 0.5 + ln(moveCount) * ln(depth / 2) / 3.0;
+ if (red >= 1.0)
+ predictedDepth -= int(floor(red * int(OnePly)));
+
+ if (predictedDepth < SelectiveDepth)
+ {
+ int preFutilityValueMargin = 0;
+ if (predictedDepth >= OnePly)
+ preFutilityValueMargin = 112 * bitScanReverse32(int(predictedDepth) * int(predictedDepth) / 2);
+
+ preFutilityValueMargin += H.gain(pos.piece_on(move_from(move)), move_from(move), move_to(move)) + 45;
+
+ futilityValueScaled = ss[ply].eval + preFutilityValueMargin - moveCount * IncrementalFutilityMargin;
+
+ if (futilityValueScaled < beta)