diff --git a/src/Lynx/Search/NegaMax.cs b/src/Lynx/Search/NegaMax.cs
index 8808cf7bf..fdc40321b 100644
--- a/src/Lynx/Search/NegaMax.cs
+++ b/src/Lynx/Search/NegaMax.cs
@@ -19,7 +19,6 @@ public sealed partial class Engine
/// Best score Side's to move's opponent can achieve, assuming best play by Side to move.
///
///
- [SkipLocalsInit]
private int NegaMax(int depth, int ply, int alpha, int beta, bool parentWasNullMove = false)
{
var position = Game.CurrentPosition;
@@ -497,156 +496,5 @@ void RevertMove()
/// Defaults to the works possible score for Black, Int.MaxValue
///
///
- [SkipLocalsInit]
- public int QuiescenceSearch(int ply, int alpha, int beta)
- {
- var position = Game.CurrentPosition;
-
- _absoluteSearchCancellationTokenSource.Token.ThrowIfCancellationRequested();
- _searchCancellationTokenSource.Token.ThrowIfCancellationRequested();
-
- if (ply >= Configuration.EngineSettings.MaxDepth)
- {
- _logger.Info("Max depth {0} reached", Configuration.EngineSettings.MaxDepth);
- return position.StaticEvaluation(Game.HalfMovesWithoutCaptureOrPawnMove).Score;
- }
-
- var pvIndex = PVTable.Indexes[ply];
- var nextPvIndex = PVTable.Indexes[ply + 1];
- _pVTable[pvIndex] = _defaultMove; // Nulling the first value before any returns
-
- var ttProbeResult = _tt.ProbeHash(position, 0, ply, alpha, beta);
- if (ttProbeResult.Score != EvaluationConstants.NoHashEntry)
- {
- return ttProbeResult.Score;
- }
- ShortMove ttBestMove = ttProbeResult.BestMove;
-
- _maxDepthReached[ply] = ply;
-
- var staticEval = ttProbeResult.NodeType != NodeType.Unknown
- ? ttProbeResult.StaticEval
- : position.StaticEvaluation(Game.HalfMovesWithoutCaptureOrPawnMove).Score;
-
- Game.UpdateStaticEvalInStack(ply, staticEval);
-
- // Beta-cutoff (updating alpha after this check)
- if (staticEval >= beta)
- {
- PrintMessage(ply - 1, "Pruning before starting quiescence search");
- return staticEval;
- }
-
- // Better move
- if (staticEval > alpha)
- {
- alpha = staticEval;
- }
-
- Span moves = stackalloc Move[Constants.MaxNumberOfPossibleMovesInAPosition];
- var pseudoLegalMoves = MoveGenerator.GenerateAllCaptures(position, moves);
- if (pseudoLegalMoves.Length == 0)
- {
- // Checking if final position first: https://github.com/lynx-chess/Lynx/pull/358
- return staticEval;
- }
-
- var nodeType = NodeType.Alpha;
- Move? bestMove = null;
- int bestScore = staticEval;
-
- bool isAnyCaptureValid = false;
-
- Span moveScores = stackalloc int[pseudoLegalMoves.Length];
- for (int i = 0; i < pseudoLegalMoves.Length; ++i)
- {
- moveScores[i] = ScoreMove(pseudoLegalMoves[i], ply, isNotQSearch: false, ttBestMove);
- }
-
- for (int i = 0; i < pseudoLegalMoves.Length; ++i)
- {
- // Incremental move sorting, inspired by https://github.com/jw1912/Chess-Challenge and suggested by toanth
- // There's no need to sort all the moves since most of them don't get checked anyway
- // So just find the first unsearched one with the best score and try it
- for (int j = i + 1; j < pseudoLegalMoves.Length; j++)
- {
- if (moveScores[j] > moveScores[i])
- {
- (moveScores[i], moveScores[j], pseudoLegalMoves[i], pseudoLegalMoves[j]) = (moveScores[j], moveScores[i], pseudoLegalMoves[j], pseudoLegalMoves[i]);
- }
- }
-
- var move = pseudoLegalMoves[i];
-
- // 🔍 QSearch SEE pruning: pruning bad captures
- if (moveScores[i] < EvaluationConstants.PromotionMoveScoreValue && moveScores[i] >= EvaluationConstants.BadCaptureMoveBaseScoreValue)
- {
- continue;
- }
-
- var gameState = position.MakeMove(move);
- if (!position.WasProduceByAValidMove())
- {
- position.UnmakeMove(move, gameState);
- continue;
- }
-
- ++_nodes;
- isAnyCaptureValid = true;
-
- PrintPreMove(position, ply, move, isQuiescence: true);
-
- // No need to check for threefold or 50 moves repetitions, since we're only searching captures, promotions, and castles
- Game.UpdateMoveinStack(ply, move);
-
-#pragma warning disable S2234 // Arguments should be passed in the same order as the method parameters
- int score = -QuiescenceSearch(ply + 1, -beta, -alpha);
-#pragma warning restore S2234 // Arguments should be passed in the same order as the method parameters
- position.UnmakeMove(move, gameState);
-
- PrintMove(position, ply, move, score, isQuiescence: true);
-
- if (score > bestScore)
- {
- bestScore = score;
-
- // Beta-cutoff
- if (score >= beta)
- {
- PrintMessage($"Pruning: {move} is enough to discard this line");
-
- _tt.RecordHash(position, staticEval, 0, ply, bestScore, NodeType.Beta, bestMove);
-
- return bestScore; // The refutation doesn't matter, since it'll be pruned
- }
-
- // Improving alpha
- if (score > alpha)
- {
- alpha = score;
- bestMove = move;
-
- _pVTable[pvIndex] = move;
- CopyPVTableMoves(pvIndex + 1, nextPvIndex, Configuration.EngineSettings.MaxDepth - ply - 1);
-
- nodeType = NodeType.Exact;
- }
- }
- }
-
- if (!isAnyCaptureValid
- && !MoveGenerator.CanGenerateAtLeastAValidMove(position)) // Bad captures can be pruned, so all moves need to be generated for now
- {
- Debug.Assert(bestMove is null);
-
- var finalEval = Position.EvaluateFinalPosition(ply, position.IsInCheck());
- _tt.RecordHash(position, staticEval, 0, ply, finalEval, NodeType.Exact);
-
- return finalEval;
- }
-
- _tt.RecordHash(position, staticEval, 0, ply, bestScore, nodeType, bestMove);
-
- return bestScore;
- }
+ public int QuiescenceSearch(int ply, int alpha, int beta) => 0;
}