Skip to content

Commit

Permalink
Merge branch 'main' into refactor/tm-outside-of-engine
Browse files Browse the repository at this point in the history
  • Loading branch information
eduherminio authored Nov 20, 2024
2 parents 5113da9 + cf6893a commit a3d1d5c
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 45 deletions.
15 changes: 4 additions & 11 deletions src/Lynx.Dev/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -561,21 +561,14 @@ static void _42_Perft()

for (int depth = 0; depth < 7; ++depth)
{
var sw = new Stopwatch();
sw.Start();
var result = Perft.Results(pos, depth);
sw.Stop();

Perft.PrintPerftResult(depth, result, Console.WriteLine);
Perft.RunPerft(pos, depth, Console.WriteLine);
}
}

static void _43_Divide()
{
var result = Perft.Divide(new Position(Constants.InitialPositionFEN), 5, Console.WriteLine);
Perft.PrintPerftResult(5, result, Console.WriteLine);
result = Perft.Divide(new Position(TrickyPosition), 5, Console.WriteLine);
Perft.PrintPerftResult(5, result, Console.WriteLine);
Perft.RunDivide(new Position(Constants.InitialPositionFEN), 5, Console.WriteLine);
Perft.RunDivide(new Position(TrickyPosition), 5, Console.WriteLine);
}

static void _44_ParseUCI()
Expand Down Expand Up @@ -1108,7 +1101,7 @@ static void TesSize(int size)
static void UnmakeMove()
{
var pos = new Position("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq");
var a = Perft.ResultsImpl(pos, 1, default);
var a = Perft.PerftRecursiveImpl(pos, 1, default);

TestMoveGen(Constants.InitialPositionFEN);
TestMoveGen(Constants.TTPositionFEN);
Expand Down
37 changes: 13 additions & 24 deletions src/Lynx/Perft.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,35 @@ namespace Lynx;
/// </summary>
public static class Perft
{
public static (long Nodes, double ElapsedSeconds) Results(Position position, int depth)
public static void RunPerft(Position position, int depth, Action<string> write)
{
var sw = new Stopwatch();
sw.Start();
var nodes = ResultsImpl(position, depth, 0);
var nodes = PerftRecursiveImpl(position, depth, 0);
sw.Stop();

return (nodes, Utils.CalculateElapsedSeconds(sw));
PrintPerftResult(depth, nodes, Utils.CalculateElapsedSeconds(sw), write);
}

public static (long Nodes, double ElapsedSeconds) Divide(Position position, int depth, Action<string> write)
public static void RunDivide(Position position, int depth, Action<string> write)
{
var sw = new Stopwatch();
sw.Start();
var nodes = DivideImpl(position, depth, 0, write);
sw.Stop();

return (nodes, Utils.CalculateElapsedSeconds(sw));
PrintPerftResult(depth, nodes, Utils.CalculateElapsedSeconds(sw), write);
}

/// <summary>
/// Proper implementation, used by <see cref="DivideImpl(Position, int, long)"/> as well
/// Proper implementation, used by <see cref="DivideImpl(Position, int, long, Action{string})"/> as well
/// </summary>
/// <param name="position"></param>
/// <param name="depth"></param>
/// <param name="nodes"></param>
/// <returns></returns>
[SkipLocalsInit]
internal static long ResultsImpl(Position position, int depth, long nodes)
internal static long PerftRecursiveImpl(Position position, int depth, long nodes)
{
if (depth != 0)
{
Expand All @@ -49,7 +49,7 @@ internal static long ResultsImpl(Position position, int depth, long nodes)

if (position.WasProduceByAValidMove())
{
nodes = ResultsImpl(position, depth - 1, nodes);
nodes = PerftRecursiveImpl(position, depth - 1, nodes);
}
position.UnmakeMove(move, state);
}
Expand All @@ -73,7 +73,7 @@ private static long DivideImpl(Position position, int depth, long nodes, Action<
if (position.WasProduceByAValidMove())
{
var accumulatedNodes = nodes;
nodes = ResultsImpl(position, depth - 1, nodes);
nodes = PerftRecursiveImpl(position, depth - 1, nodes);

write($"{move.UCIString()}\t\t{nodes - accumulatedNodes}");
}
Expand All @@ -89,26 +89,15 @@ private static long DivideImpl(Position position, int depth, long nodes, Action<
return nodes + 1;
}

public static void PrintPerftResult(int depth, (long Nodes, double ElapsedSeconds) peftResult, Action<string> write)
private static void PrintPerftResult(int depth, long nodes, double elapsedSeconds, Action<string> write)
{
var timeStr = TimeToString(peftResult.ElapsedSeconds * 1_000);
var timeStr = TimeToString(elapsedSeconds * 1_000);

write(
$"Depth:\t{depth}" + Environment.NewLine +
$"Nodes:\t{peftResult.Nodes}" + Environment.NewLine +
$"Nodes:\t{nodes}" + Environment.NewLine +
$"Time:\t{timeStr}" + Environment.NewLine +
$"nps:\t{peftResult.Nodes / (peftResult.ElapsedSeconds * 1_000_000):F} Mnps" + Environment.NewLine);
}

public static async ValueTask PrintPerftResult(int depth, (long Nodes, double ElapsedSeconds) peftResult, Func<string, ValueTask> write)
{
var timeStr = TimeToString(peftResult.ElapsedSeconds * 1_000);

await write(
$"Depth:\t{depth}" + Environment.NewLine +
$"Nodes:\t{peftResult.Nodes}" + Environment.NewLine +
$"Time:\t{timeStr}" + Environment.NewLine +
$"nps:\t{peftResult.Nodes / (peftResult.ElapsedSeconds * 1_000_000):F} Mnps" + Environment.NewLine);
$"nps:\t{nodes / (elapsedSeconds * 1_000_000):F} Mnps" + Environment.NewLine);
}

private static string TimeToString(double milliseconds)
Expand Down
14 changes: 6 additions & 8 deletions src/Lynx/UCIHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ static ReadOnlySpan<char> ExtractCommandItems(string rawCommand)
HandleNewGame();
break;
case "perft":
await HandlePerft(rawCommand);
HandlePerft(rawCommand);
break;
case "divide":
await HandleDivide(rawCommand);
HandleDivide(rawCommand);
break;
case "bench":
await HandleBench(rawCommand);
Expand Down Expand Up @@ -556,25 +556,23 @@ private void HandleQuit()

private void HandleRegister(ReadOnlySpan<char> rawCommand) => _engine.Registration = new RegisterCommand(rawCommand);

private async Task HandlePerft(string rawCommand)
private void HandlePerft(string rawCommand)
{
var items = rawCommand.Split(' ', StringSplitOptions.RemoveEmptyEntries);

if (items.Length >= 2 && int.TryParse(items[1], out int depth) && depth >= 1)
{
var results = Perft.Results(_engine.Game.CurrentPosition, depth);
await Perft.PrintPerftResult(depth, results, str => _engineToUci.Writer.WriteAsync(str));
Perft.RunPerft(_engine.Game.CurrentPosition, depth, str => _engineToUci.Writer.TryWrite(str));
}
}

private async ValueTask HandleDivide(string rawCommand)
private void HandleDivide(string rawCommand)
{
var items = rawCommand.Split(' ', StringSplitOptions.RemoveEmptyEntries);

if (items.Length >= 2 && int.TryParse(items[1], out int depth) && depth >= 1)
{
var results = Perft.Divide(_engine.Game.CurrentPosition, depth, str => _engineToUci.Writer.TryWrite(str));
await Perft.PrintPerftResult(depth, results, str => _engineToUci.Writer.WriteAsync(str));
Perft.RunDivide(_engine.Game.CurrentPosition, depth, str => _engineToUci.Writer.TryWrite(str));
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Lynx.Test/PerftTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,6 @@ public void MartinnPositions(string fen, int depth, long expectedNumberOfNodes)

private static void Validate(string fen, int depth, long expectedNumberOfNodes)
{
Assert.AreEqual(expectedNumberOfNodes, Perft.ResultsImpl(new Position(fen), depth, default));
Assert.AreEqual(expectedNumberOfNodes, Perft.PerftRecursiveImpl(new Position(fen), depth, default));
}
}
2 changes: 1 addition & 1 deletion tests/Lynx.Test/PerftTestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,6 @@ public void Suite(string fen, int depth, long expectedNumberOfNodes)

private static void Validate(string fen, int depth, long expectedNumberOfNodes)
{
Assert.AreEqual(expectedNumberOfNodes, Perft.ResultsImpl(new Position(fen), depth, default));
Assert.AreEqual(expectedNumberOfNodes, Perft.PerftRecursiveImpl(new Position(fen), depth, default));
}
}

0 comments on commit a3d1d5c

Please sign in to comment.