+ // Step 14. Extensions (~75 Elo)
+
+ // Singular extension search (~70 Elo). If all moves but one fail low on a
+ // search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
+ // then that move is singular and should be extended. To verify this we do
+ // a reduced search on all the other moves but the ttMove and if the
+ // result is lower than ttValue minus a margin then we will extend the ttMove.
+ if ( depth >= 6
+ && move == ttMove
+ && !rootNode
+ && !excludedMove // Avoid recursive singular search
+ /* && ttValue != VALUE_NONE Already implicit in the next condition */
+ && abs(ttValue) < VALUE_KNOWN_WIN
+ && (tte->bound() & BOUND_LOWER)
+ && tte->depth() >= depth - 3
+ && pos.legal(move))
+ {
+ Value singularBeta = ttValue - 2 * depth;
+ Depth halfDepth = depth / 2;
+ ss->excludedMove = move;
+ value = search<NonPV>(pos, ss, singularBeta - 1, singularBeta, halfDepth, cutNode);
+ ss->excludedMove = MOVE_NONE;
+
+ if (value < singularBeta)
+ {
+ extension = 1;
+ singularLMR = true;
+ }
+
+ // Multi-cut pruning
+ // Our ttMove is assumed to fail high, and now we failed high also on a reduced
+ // search without the ttMove. So we assume this expected Cut-node is not singular,
+ // that multiple moves fail high, and we can prune the whole subtree by returning
+ // a soft bound.
+ else if (singularBeta >= beta)
+ return singularBeta;
+ }
+
+ // Check extension (~2 Elo)
+ else if ( givesCheck
+ && (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
+ extension = 1;
+
+ // Passed pawn extension
+ else if ( move == ss->killers[0]
+ && pos.advanced_pawn_push(move)
+ && pos.pawn_passed(us, to_sq(move)))
+ extension = 1;
+
+ // Last captures extension
+ else if ( PieceValue[EG][pos.captured_piece()] > PawnValueEg
+ && pos.non_pawn_material() <= 2 * RookValueMg)
+ extension = 1;
+
+ // Castling extension
+ if (type_of(move) == CASTLING)
+ extension = 1;
+
+ // Add extension to new depth
+ newDepth += extension;
+