@@ -1100,72 +1100,68 @@ Value Search::Worker::search(
11001100 }
11011101
11021102 // Step 15. Extensions
1103- // We take care to not overdo to avoid search getting stuck.
1104- if (ss->ply < thisThread->rootDepth * 2 )
1103+ // Singular extension search. If all moves but one
1104+ // fail low on a search of (alpha-s, beta-s), and just one fails high on
1105+ // (alpha, beta), then that move is singular and should be extended. To
1106+ // verify this we do a reduced search on the position excluding the ttMove
1107+ // and if the result is lower than ttValue minus a margin, then we will
1108+ // extend the ttMove. Recursive singular search is avoided.
1109+
1110+ // (*Scaler) Generally, higher singularBeta (i.e closer to ttValue)
1111+ // and lower extension margins scale well.
1112+
1113+ if (!rootNode && move == ttData.move && !excludedMove
1114+ && depth >= 6 - (thisThread->completedDepth > 27 ) + ss->ttPv && is_valid (ttData.value )
1115+ && !is_decisive (ttData.value ) && (ttData.bound & BOUND_LOWER)
1116+ && ttData.depth >= depth - 3 )
11051117 {
1106- // Singular extension search. If all moves but one
1107- // fail low on a search of (alpha-s, beta-s), and just one fails high on
1108- // (alpha, beta), then that move is singular and should be extended. To
1109- // verify this we do a reduced search on the position excluding the ttMove
1110- // and if the result is lower than ttValue minus a margin, then we will
1111- // extend the ttMove. Recursive singular search is avoided.
1112-
1113- // (*Scaler) Generally, higher singularBeta (i.e closer to ttValue)
1114- // and lower extension margins scale well.
1115-
1116- if (!rootNode && move == ttData.move && !excludedMove
1117- && depth >= 6 - (thisThread->completedDepth > 27 ) + ss->ttPv
1118- && is_valid (ttData.value ) && !is_decisive (ttData.value )
1119- && (ttData.bound & BOUND_LOWER) && ttData.depth >= depth - 3 )
1120- {
1121- Value singularBeta = ttData.value - (58 + 76 * (ss->ttPv && !PvNode)) * depth / 57 ;
1122- Depth singularDepth = newDepth / 2 ;
1123-
1124- ss->excludedMove = move;
1125- value =
1126- search<NonPV>(pos, ss, singularBeta - 1 , singularBeta, singularDepth, cutNode);
1127- ss->excludedMove = Move::none ();
1128-
1129- if (value < singularBeta)
1130- {
1131- int corrValAdj1 = std::abs (correctionValue) / 248400 ;
1132- int corrValAdj2 = std::abs (correctionValue) / 249757 ;
1133- int doubleMargin = -4 + 244 * PvNode - 206 * !ttCapture - corrValAdj1
1134- - 997 * ttMoveHistory / 131072 ;
1135- int tripleMargin =
1136- 84 + 269 * PvNode - 253 * !ttCapture + 91 * ss->ttPv - corrValAdj2;
1137-
1138- extension = 1 + (value < singularBeta - doubleMargin)
1139- + (value < singularBeta - tripleMargin);
1118+ Value singularBeta = ttData.value - (58 + 76 * (ss->ttPv && !PvNode)) * depth / 57 ;
1119+ Depth singularDepth = newDepth / 2 ;
11401120
1141- depth++;
1142- }
1143-
1144- // Multi-cut pruning
1145- // Our ttMove is assumed to fail high based on the bound of the TT entry,
1146- // and if after excluding the ttMove with a reduced search we fail high
1147- // over the original beta, we assume this expected cut-node is not
1148- // singular (multiple moves fail high), and we can prune the whole
1149- // subtree by returning a softbound.
1150- else if (value >= beta && !is_decisive (value))
1151- return value;
1121+ ss->excludedMove = move;
1122+ value = search<NonPV>(pos, ss, singularBeta - 1 , singularBeta, singularDepth, cutNode);
1123+ ss->excludedMove = Move::none ();
11521124
1153- // Negative extensions
1154- // If other moves failed high over (ttValue - margin) without the
1155- // ttMove on a reduced search, but we cannot do multi-cut because
1156- // (ttValue - margin) is lower than the original beta, we do not know
1157- // if the ttMove is singular or can do a multi-cut, so we reduce the
1158- // ttMove in favor of other moves based on some conditions:
1159-
1160- // If the ttMove is assumed to fail high over current beta
1161- else if (ttData.value >= beta)
1162- extension = -3 ;
1163-
1164- // If we are on a cutNode but the ttMove is not assumed to fail high
1165- // over current beta
1166- else if (cutNode)
1167- extension = -2 ;
1125+ if (value < singularBeta)
1126+ {
1127+ int corrValAdj1 = std::abs (correctionValue) / 248400 ;
1128+ int corrValAdj2 = std::abs (correctionValue) / 249757 ;
1129+ int doubleMargin = -4 + 244 * PvNode - 206 * !ttCapture - corrValAdj1
1130+ - 997 * ttMoveHistory / 131072
1131+ - (ss->ply * 2 > thisThread->rootDepth * 3 ) * 47 ;
1132+ int tripleMargin = 84 + 269 * PvNode - 253 * !ttCapture + 91 * ss->ttPv
1133+ - corrValAdj2 - (ss->ply * 2 > thisThread->rootDepth * 3 ) * 54 ;
1134+
1135+ extension =
1136+ 1 + (value < singularBeta - doubleMargin) + (value < singularBeta - tripleMargin);
1137+
1138+ depth++;
11681139 }
1140+
1141+ // Multi-cut pruning
1142+ // Our ttMove is assumed to fail high based on the bound of the TT entry,
1143+ // and if after excluding the ttMove with a reduced search we fail high
1144+ // over the original beta, we assume this expected cut-node is not
1145+ // singular (multiple moves fail high), and we can prune the whole
1146+ // subtree by returning a softbound.
1147+ else if (value >= beta && !is_decisive (value))
1148+ return value;
1149+
1150+ // Negative extensions
1151+ // If other moves failed high over (ttValue - margin) without the
1152+ // ttMove on a reduced search, but we cannot do multi-cut because
1153+ // (ttValue - margin) is lower than the original beta, we do not know
1154+ // if the ttMove is singular or can do a multi-cut, so we reduce the
1155+ // ttMove in favor of other moves based on some conditions:
1156+
1157+ // If the ttMove is assumed to fail high over current beta
1158+ else if (ttData.value >= beta)
1159+ extension = -3 ;
1160+
1161+ // If we are on a cutNode but the ttMove is not assumed to fail high
1162+ // over current beta
1163+ else if (cutNode)
1164+ extension = -2 ;
11691165 }
11701166
11711167 // Step 16. Make the move
0 commit comments