+ ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, singleEvasion, mateThreat, &dangerous);
+
+ // Singular extension search. We extend the TT move if its value is much better than
+ // its siblings. To verify this we do a reduced search on all the other moves but the
+ // ttMove, if result is lower then ttValue minus a margin then we extend ttMove.
+ if ( depth >= 8 * OnePly
+ && tte
+ && move == tte->move()
+ && !excludedMove // Do not allow recursive single-reply search
+ && ext < OnePly
+ && is_lower_bound(tte->type())
+ && tte->depth() >= depth - 3 * OnePly)
+ {
+ Value ttValue = value_from_tt(tte->value(), ply);
+
+ if (abs(ttValue) < VALUE_KNOWN_WIN)
+ {
+ Value excValue = search(pos, ss, ttValue - SingleReplyMargin, depth / 2, ply, false, threadID, move);
+
+ 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;
+ }
+ }