Skip to content

Commit

Permalink
Implement TT in quiescence search
Browse files Browse the repository at this point in the history
  • Loading branch information
eduherminio committed Aug 4, 2023
1 parent 4a41761 commit e108850
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
7 changes: 0 additions & 7 deletions src/Lynx/Search/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,6 @@ private int Score(Move move, in Position position, int depth, Move bestMoveTTCan
return move.Score(in position, _killerMoves, depth, _historyMoves);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private IOrderedEnumerable<Move> SortCaptures(IEnumerable<Move> moves, in Position currentPosition, int depth)
{
var localPosition = currentPosition;
return moves.OrderByDescending(move => Score(move, in localPosition, depth));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CopyPVTableMoves(int target, int source, int moveCountToCopy)
{
Expand Down
41 changes: 30 additions & 11 deletions src/Lynx/Search/NegaMax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private int NegaMax(in Position position, int minDepth, int targetDepth, int ply
if (ply > 0)
{
var ttProbeResult = _transpositionTable.ProbeHash(position, targetDepth, ply, alpha, beta);
if (ttProbeResult.Evaluation != EvaluationConstants.NoHashEntry) // TODO here we can try alpha == beta - 1 as requirement
if (ttProbeResult.Evaluation != EvaluationConstants.NoHashEntry)
{
return ttProbeResult.Evaluation;
}
Expand All @@ -60,7 +60,7 @@ private int NegaMax(in Position position, int minDepth, int targetDepth, int ply
{
if (new Position(in position, candidateMove).WasProduceByAValidMove())
{
return QuiescenceSearch(in position, ply, alpha, beta);
return QuiescenceSearch(in position, targetDepth, ply, alpha, beta);
}
}

Expand Down Expand Up @@ -110,7 +110,6 @@ private int NegaMax(in Position position, int minDepth, int targetDepth, int ply
VerifiedNullMovePruning_SearchAgain:

var nodeType = NodeType.Alpha;

int movesSearched = 0;
Move? bestMove = null;
bool isAnyMoveValid = false;
Expand Down Expand Up @@ -275,7 +274,7 @@ private int NegaMax(in Position position, int minDepth, int targetDepth, int ply
/// Defaults to the works possible score for Black, Int.MaxValue
/// </param>
/// <returns></returns>
public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)
public int QuiescenceSearch(in Position position, int targetDepth, int ply, int alpha, int beta)
{
_absoluteSearchCancellationTokenSource.Token.ThrowIfCancellationRequested();
//_searchCancellationTokenSource.Token.ThrowIfCancellationRequested();
Expand All @@ -284,6 +283,15 @@ public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)
var nextPvIndex = PVTable.Indexes[ply + 1];
_pVTable[pvIndex] = _defaultMove; // Nulling the first value before any returns

Move ttBestMove = default;

var ttProbeResult = _transpositionTable.ProbeHash(position, targetDepth, ply, alpha, beta); // We need to make sure that
if (ttProbeResult.Evaluation != EvaluationConstants.NoHashEntry)
{
return ttProbeResult.Evaluation;
}
ttBestMove = ttProbeResult.BestMove;

++_nodes;
_maxDepthReached[ply] = ply;

Expand All @@ -308,12 +316,14 @@ public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)
return staticEvaluation; // TODO check if in check or drawn position
}

var movesToEvaluate = SortCaptures(generatedMoves, in position, ply);

var nodeType = NodeType.Alpha;
Move? bestMove = null;
bool isAnyMoveValid = false;
var localPosition = position;

var pseudoLegalMoves = generatedMoves.OrderByDescending(move => Score(move, in localPosition, ply, ttBestMove));

foreach (var move in movesToEvaluate)
foreach (var move in pseudoLegalMoves)
{
var newPosition = new Position(in position, move);
if (!newPosition.WasProduceByAValidMove())
Expand Down Expand Up @@ -341,7 +351,7 @@ public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)
}
else
{
evaluation = -QuiescenceSearch(in newPosition, ply + 1, -beta, -alpha);
evaluation = -QuiescenceSearch(in newPosition, targetDepth, ply + 1, -beta, -alpha);
}

// After making a move
Expand All @@ -357,6 +367,9 @@ public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)
if (evaluation >= beta)
{
PrintMessage($"Pruning: {move} is enough to discard this line");

_transpositionTable.RecordHash(position, targetDepth, ply, beta, NodeType.Beta, bestMove);

return evaluation; // The refutation doesn't matter, since it'll be pruned
}

Expand All @@ -367,27 +380,33 @@ public int QuiescenceSearch(in Position position, int ply, int alpha, int beta)

_pVTable[pvIndex] = move;
CopyPVTableMoves(pvIndex + 1, nextPvIndex, Configuration.EngineSettings.MaxDepth - ply - 1);

nodeType = NodeType.Exact;
}
}

if (bestMove is null)
{
if (isAnyMoveValid)
{
return alpha;
goto ReturnAlpha;
}

foreach (var move in position.AllPossibleMoves(Game.MovePool))
{
if (new Position(in position, move).WasProduceByAValidMove())
{
return alpha;
goto ReturnAlpha;
}
}

return Position.EvaluateFinalPosition(ply, position.IsInCheck());
var finalEval = Position.EvaluateFinalPosition(ply, position.IsInCheck());
_transpositionTable.RecordHash(position, targetDepth, ply, finalEval, NodeType.Exact);
}

ReturnAlpha:
_transpositionTable.RecordHash(position, targetDepth, ply, alpha, nodeType, bestMove);

// Node fails low
return alpha;
}
Expand Down

0 comments on commit e108850

Please sign in to comment.