Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔍 Add basic LMP #512

Merged
merged 10 commits into from
Nov 24, 2023
4 changes: 4 additions & 0 deletions src/Lynx.Cli/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@

"IIR_MinDepth": 4,

"LMP_MaxDepth": 2,
"LMP_BaseMovesToTry": 0,
"LMP_MovesDepthMultiplier": 10,

"History_MaxMoveValue": 8192,

// Evaluation
Expand Down
6 changes: 6 additions & 0 deletions src/Lynx/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ public sealed class EngineSettings

public int IIR_MinDepth { get; set; } = 4;

public int LMP_MaxDepth { get; set; } = 2;

public int LMP_BaseMovesToTry { get; set; } = 0;

public int LMP_MovesDepthMultiplier { get; set; } = 10;

public int History_MaxMoveValue { get; set; } = 8_192;

#region Evaluation
Expand Down
29 changes: 24 additions & 5 deletions src/Lynx/Search/NegaMax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,20 +182,20 @@ private int NegaMax(int depth, int ply, int alpha, int beta, bool parentWasNullM
}
}

for (int i = 0; i < pseudoLegalMoves.Length; ++i)
for (int moveIndex = 0; moveIndex < pseudoLegalMoves.Length; ++moveIndex)
{
// 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++)
for (int j = moveIndex + 1; j < pseudoLegalMoves.Length; j++)
{
if (scores[j] > scores[i])
if (scores[j] > scores[moveIndex])
{
(scores[i], scores[j], pseudoLegalMoves[i], pseudoLegalMoves[j]) = (scores[j], scores[i], pseudoLegalMoves[j], pseudoLegalMoves[i]);
(scores[moveIndex], scores[j], pseudoLegalMoves[moveIndex], pseudoLegalMoves[j]) = (scores[j], scores[moveIndex], pseudoLegalMoves[j], pseudoLegalMoves[moveIndex]);
}
}

var move = pseudoLegalMoves[i];
var move = pseudoLegalMoves[moveIndex];

var gameState = position.MakeMove(move);

Expand Down Expand Up @@ -231,6 +231,25 @@ private int NegaMax(int depth, int ply, int alpha, int beta, bool parentWasNullM
}
else
{
// Late Move Pruning (LMP) - all quiet moves can be pruned
// after searching the first few given by the move ordering algorithm
if (!pvNode
&& !isInCheck
&& depth <= Configuration.EngineSettings.LMP_MaxDepth
&& scores[moveIndex] < EvaluationConstants.PromotionMoveScoreValue // Quiet moves
&& moveIndex >= Configuration.EngineSettings.LMP_BaseMovesToTry + (Configuration.EngineSettings.LMP_MovesDepthMultiplier * depth)) // Based on formula suggested by Antares
{
// After making a move
Game.HalfMovesWithoutCaptureOrPawnMove = oldValue;
if (!isThreeFoldRepetition)
{
Game.PositionHashHistory.Remove(position.UniqueIdentifier);
}
position.UnmakeMove(move, gameState);

break;
}

int reduction = 0;

// 🔍 Late Move Reduction (LMR) - search with reduced depth
Expand Down
Loading