diff --git a/.gitignore b/.gitignore index 8a30d258e..234892258 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,8 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +.idea/.idea.Chess-Challenge/.idea/.gitignore +.idea/.idea.Chess-Challenge/.idea/.name +.idea/.idea.Chess-Challenge/.idea/encodings.xml +.idea/.idea.Chess-Challenge/.idea/indexLayout.xml +.idea/.idea.Chess-Challenge/.idea/vcs.xml diff --git a/Chess-Challenge.sln b/Chess-Challenge.sln index 396059030..c4963e209 100644 --- a/Chess-Challenge.sln +++ b/Chess-Challenge.sln @@ -3,23 +3,29 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32901.215 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Chess-Challenge", "Chess-Challenge\Chess-Challenge.csproj", "{2803E64F-15AC-430B-A5A2-69C00EA7505F}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9FC5D849-F0B6-4C89-A541-C36A341AE67C}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChessEngine", "ChessEngine\ChessEngine.csproj", "{BB20BD5E-BC39-43AF-AB33-F7DD3139B531}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChessChallenge", "ChessChallenge\ChessChallenge.csproj", "{0B1CE8E2-50C2-4316-8F0D-92119649D6FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2803E64F-15AC-430B-A5A2-69C00EA7505F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2803E64F-15AC-430B-A5A2-69C00EA7505F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2803E64F-15AC-430B-A5A2-69C00EA7505F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2803E64F-15AC-430B-A5A2-69C00EA7505F}.Release|Any CPU.Build.0 = Release|Any CPU + {BB20BD5E-BC39-43AF-AB33-F7DD3139B531}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB20BD5E-BC39-43AF-AB33-F7DD3139B531}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB20BD5E-BC39-43AF-AB33-F7DD3139B531}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB20BD5E-BC39-43AF-AB33-F7DD3139B531}.Release|Any CPU.Build.0 = Release|Any CPU + {0B1CE8E2-50C2-4316-8F0D-92119649D6FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B1CE8E2-50C2-4316-8F0D-92119649D6FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B1CE8E2-50C2-4316-8F0D-92119649D6FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B1CE8E2-50C2-4316-8F0D-92119649D6FF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Chess-Challenge/src/API/PieceType.cs b/Chess-Challenge/src/API/PieceType.cs deleted file mode 100644 index 7f2f33dcf..000000000 --- a/Chess-Challenge/src/API/PieceType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ChessChallenge.API -{ - public enum PieceType - { - None, // 0 - Pawn, // 1 - Knight, // 2 - Bishop, // 3 - Rook, // 4 - Queen, // 5 - King // 6 - } -} diff --git a/Chess-Challenge/Chess-Challenge.csproj b/ChessChallenge/ChessChallenge.csproj similarity index 76% rename from Chess-Challenge/Chess-Challenge.csproj rename to ChessChallenge/ChessChallenge.csproj index 4b6d061f8..5c28f4ee3 100644 --- a/Chess-Challenge/Chess-Challenge.csproj +++ b/ChessChallenge/ChessChallenge.csproj @@ -2,34 +2,28 @@ Exe - net6.0 - Chess_Challenge + net8.0 + ChessChallenge disable enable True + 11 - - - src\Token Counter\Microsoft.CodeAnalysis.dll - - - src\Token Counter\Microsoft.CodeAnalysis.CSharp.dll - - + - - Always - Never - + + Always + + Always @@ -50,11 +44,20 @@ - + - + + + + + + src\Framework\TokenCounting\Microsoft.CodeAnalysis.dll + + + src\Framework\TokenCounting\Microsoft.CodeAnalysis.CSharp.dll + diff --git a/Chess-Challenge/resources/Fens.txt b/ChessChallenge/resources/Fens.txt similarity index 100% rename from Chess-Challenge/resources/Fens.txt rename to ChessChallenge/resources/Fens.txt diff --git a/Chess-Challenge/resources/Fonts/OPENSANS-SEMIBOLD.TTF b/ChessChallenge/resources/Fonts/OPENSANS-SEMIBOLD.TTF similarity index 100% rename from Chess-Challenge/resources/Fonts/OPENSANS-SEMIBOLD.TTF rename to ChessChallenge/resources/Fonts/OPENSANS-SEMIBOLD.TTF diff --git a/Chess-Challenge/resources/Fonts/sdf.fs b/ChessChallenge/resources/Fonts/sdf.fs similarity index 100% rename from Chess-Challenge/resources/Fonts/sdf.fs rename to ChessChallenge/resources/Fonts/sdf.fs diff --git a/Chess-Challenge/resources/Pieces.png b/ChessChallenge/resources/Pieces.png similarity index 100% rename from Chess-Challenge/resources/Pieces.png rename to ChessChallenge/resources/Pieces.png diff --git a/Chess-Challenge/src/Evil Bot/EvilBot.cs b/ChessChallenge/src/Bots/EvilBot.cs similarity index 95% rename from Chess-Challenge/src/Evil Bot/EvilBot.cs rename to ChessChallenge/src/Bots/EvilBot.cs index b70d8e1f8..7b61510ae 100644 --- a/Chess-Challenge/src/Evil Bot/EvilBot.cs +++ b/ChessChallenge/src/Bots/EvilBot.cs @@ -1,7 +1,7 @@ -using ChessChallenge.API; -using System; +using System; +using ChessEngine; -namespace ChessChallenge.Example +namespace ChessChallenge.Bots { // A simple bot that can spot mate in one, and always captures the most valuable piece it can. // Plays randomly otherwise. diff --git a/Chess-Challenge/src/My Bot/MyBot.cs b/ChessChallenge/src/Bots/MyBot.cs similarity index 60% rename from Chess-Challenge/src/My Bot/MyBot.cs rename to ChessChallenge/src/Bots/MyBot.cs index 3c2a704a7..0a5afe3a4 100644 --- a/Chess-Challenge/src/My Bot/MyBot.cs +++ b/ChessChallenge/src/Bots/MyBot.cs @@ -1,6 +1,8 @@ -using ChessChallenge.API; +using ChessEngine; -public class MyBot : IChessBot +namespace ChessChallenge.Bots; + +public class DefaultBot : IChessBot { public Move Think(Board board, Timer timer) { diff --git a/Chess-Challenge/src/Framework/Application/Core/ChallengeController.cs b/ChessChallenge/src/Framework/Application/Core/ChallengeController.cs similarity index 89% rename from Chess-Challenge/src/Framework/Application/Core/ChallengeController.cs rename to ChessChallenge/src/Framework/Application/Core/ChallengeController.cs index 4d6822875..e47f3795b 100644 --- a/Chess-Challenge/src/Framework/Application/Core/ChallengeController.cs +++ b/ChessChallenge/src/Framework/Application/Core/ChallengeController.cs @@ -1,17 +1,25 @@ -using ChessChallenge.Chess; -using ChessChallenge.Example; -using Raylib_cs; -using System; +using System; using System.IO; using System.Linq; using System.Runtime.ExceptionServices; using System.Text; using System.Threading; using System.Threading.Tasks; -using static ChessChallenge.Application.Settings; -using static ChessChallenge.Application.ConsoleHelper; - -namespace ChessChallenge.Application +using ChessChallenge.Bots; +using ChessChallenge.Framework.Application.Helpers; +using ChessChallenge.Framework.Application.Players; +using ChessChallenge.Framework.Application.TokenCounting; +using ChessChallenge.Framework.Application.UI; +using Raylib_cs; +using static ChessChallenge.Framework.Application.Core.Settings; +using static ChessChallenge.Framework.Application.Helpers.ConsoleHelper; +using ChessEngine; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration; +using ChessEngine.Internal.Result; +using Board = ChessEngine.Internal.Board.Board; + +namespace ChessChallenge.Framework.Application.Core { public class ChallengeController { @@ -32,7 +40,7 @@ public enum PlayerType float lastMoveMadeTime; bool isWaitingToPlayMove; - Move moveToPlay; + ChessEngine.Internal.Board.Move moveToPlay; float playMoveTime; public bool HumanWasWhiteLastGame { get; private set; } @@ -58,7 +66,7 @@ public enum PlayerType public ChallengeController() { - Log($"Launching Chess-Challenge version {Settings.Version}"); + Log($"Launching ChessChallenge version {Settings.Version}"); (tokenCount, debugTokenCount) = GetTokenCount(); Warmer.Warm(); @@ -141,14 +149,14 @@ void BotThinkerThread() //Console.WriteLine("Exitting thread: " + threadID); } - Move GetBotMove() + ChessEngine.Internal.Board.Move GetBotMove() { - API.Board botBoard = new(board); + ChessEngine.Board botBoard = new(board); try { - API.Timer timer = new(PlayerToMove.TimeRemainingMs, PlayerNotOnMove.TimeRemainingMs, GameDurationMilliseconds, IncrementMilliseconds); - API.Move move = PlayerToMove.Bot.Think(botBoard, timer); - return new Move(move.RawValue); + ChessEngine.Timer timer = new(PlayerToMove.TimeRemainingMs, PlayerNotOnMove.TimeRemainingMs, GameDurationMilliseconds, IncrementMilliseconds); + Move move = PlayerToMove.Bot.Think(botBoard, timer); + return new ChessEngine.Internal.Board.Move(move.RawValue); } catch (Exception e) { @@ -156,7 +164,7 @@ Move GetBotMove() hasBotTaskException = true; botExInfo = ExceptionDispatchInfo.Capture(e); } - return Move.NullMove; + return ChessEngine.Internal.Board.Move.NullMove; } @@ -194,13 +202,13 @@ void SetBoardPerspective() boardUI.SetPerspective(PlayerWhite.IsHuman); HumanWasWhiteLastGame = PlayerWhite.IsHuman; } - else if (PlayerWhite.Bot is MyBot && PlayerBlack.Bot is MyBot) + else if (PlayerWhite.Bot is DefaultBot && PlayerBlack.Bot is DefaultBot) { boardUI.SetPerspective(true); } else { - boardUI.SetPerspective(PlayerWhite.Bot is MyBot); + boardUI.SetPerspective(PlayerWhite.Bot is DefaultBot); } } @@ -208,7 +216,7 @@ ChessPlayer CreatePlayer(PlayerType type) { return type switch { - PlayerType.MyBot => new ChessPlayer(new MyBot(), type, GameDurationMilliseconds), + PlayerType.MyBot => new ChessPlayer(new DefaultBot(), type, GameDurationMilliseconds), PlayerType.EvilBot => new ChessPlayer(new EvilBot(), type, GameDurationMilliseconds), _ => new ChessPlayer(new HumanPlayer(boardUI), type) }; @@ -216,14 +224,14 @@ ChessPlayer CreatePlayer(PlayerType type) static (int totalTokenCount, int debugTokenCount) GetTokenCount() { - string path = Path.Combine(Directory.GetCurrentDirectory(), "src", "My Bot", "MyBot.cs"); + string path = Path.Combine(Directory.GetCurrentDirectory(), "src", "Bots", "MyBot.cs"); using StreamReader reader = new(path); string txt = reader.ReadToEnd(); return TokenCounter.CountTokens(txt); } - void OnMoveChosen(Move chosenMove) + void OnMoveChosen(ChessEngine.Internal.Board.Move chosenMove) { if (IsLegal(chosenMove)) { @@ -249,7 +257,7 @@ void OnMoveChosen(Move chosenMove) } } - void PlayMove(Move move) + void PlayMove(ChessEngine.Internal.Board.Move move) { if (isPlaying) { @@ -424,7 +432,7 @@ public void StartNewBotMatch(PlayerType botTypeA, PlayerType botTypeB) public string AllPGNs => pgns.ToString(); - bool IsLegal(Move givenMove) + bool IsLegal(ChessEngine.Internal.Board.Move givenMove) { var moves = moveGenerator.GenerateMoves(board); foreach (var legalMove in moves) diff --git a/Chess-Challenge/src/Framework/Application/Core/Program.cs b/ChessChallenge/src/Framework/Application/Core/Program.cs similarity index 95% rename from Chess-Challenge/src/Framework/Application/Core/Program.cs rename to ChessChallenge/src/Framework/Application/Core/Program.cs index 134db7645..b4f657852 100644 --- a/Chess-Challenge/src/Framework/Application/Core/Program.cs +++ b/ChessChallenge/src/Framework/Application/Core/Program.cs @@ -1,9 +1,10 @@ -using Raylib_cs; -using System.IO; +using System.IO; using System.Numerics; using System.Runtime.InteropServices; +using ChessChallenge.Framework.Application.Helpers; +using Raylib_cs; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Core { static class Program { diff --git a/Chess-Challenge/src/Framework/Application/Core/Settings.cs b/ChessChallenge/src/Framework/Application/Core/Settings.cs similarity index 94% rename from Chess-Challenge/src/Framework/Application/Core/Settings.cs rename to ChessChallenge/src/Framework/Application/Core/Settings.cs index b1a5fa42f..9762c56d6 100644 --- a/Chess-Challenge/src/Framework/Application/Core/Settings.cs +++ b/ChessChallenge/src/Framework/Application/Core/Settings.cs @@ -1,6 +1,6 @@ using System.Numerics; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Core { public static class Settings { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/ConsoleHelper.cs b/ChessChallenge/src/Framework/Application/Helpers/ConsoleHelper.cs similarity index 79% rename from Chess-Challenge/src/Framework/Application/Helpers/ConsoleHelper.cs rename to ChessChallenge/src/Framework/Application/Helpers/ConsoleHelper.cs index aab3b40b8..a45901606 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/ConsoleHelper.cs +++ b/ChessChallenge/src/Framework/Application/Helpers/ConsoleHelper.cs @@ -1,7 +1,7 @@ using System; -using static ChessChallenge.Application.Settings; +using static ChessChallenge.Framework.Application.Core.Settings; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Helpers { public static class ConsoleHelper { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/FileHelper.cs b/ChessChallenge/src/Framework/Application/Helpers/FileHelper.cs similarity index 96% rename from Chess-Challenge/src/Framework/Application/Helpers/FileHelper.cs rename to ChessChallenge/src/Framework/Application/Helpers/FileHelper.cs index 7bf3907a7..63b066101 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/FileHelper.cs +++ b/ChessChallenge/src/Framework/Application/Helpers/FileHelper.cs @@ -1,9 +1,9 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Helpers { public static class FileHelper { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/Tester.cs b/ChessChallenge/src/Framework/Application/Helpers/Tester.cs similarity index 91% rename from Chess-Challenge/src/Framework/Application/Helpers/Tester.cs rename to ChessChallenge/src/Framework/Application/Helpers/Tester.cs index fae228f7e..dae1da3e0 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/Tester.cs +++ b/ChessChallenge/src/Framework/Application/Helpers/Tester.cs @@ -1,16 +1,16 @@ -using ChessChallenge.API; -using ChessChallenge.Application.APIHelpers; -using ChessChallenge.Chess; -using System; +using System; +using ChessEngine; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Helpers { public static class Tester { const bool throwOnAssertFail = false; static MoveGenerator moveGen; - static API.Board boardAPI; + static Board boardAPI; static bool anyFailed; @@ -56,7 +56,7 @@ public static void RunPerft(bool useStackalloc = true) string[] fens = { "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", "2b1b3/1r1P4/3K3p/1p6/2p5/6k1/1P3p2/4B3 w - - 0 42", "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -", "r3k2r/pp3pp1/PN1pr1p1/4p1P1/4P3/3P4/P1P2PP1/R3K2R w KQkq - 4 4", "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8", "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10", "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -", "r3k1nr/p2pp1pp/b1n1P1P1/1BK1Pp1q/8/8/2PP1PPP/6N1 w kq - 0 1", "3k4/3p4/8/K1P4r/8/8/8/8 b - - 0 1", "8/8/1k6/2b5/2pP4/8/5K2/8 b - d3 0 1", "5k2/8/8/8/8/8/8/4K2R w K - 0 1", "3k4/8/8/8/8/8/8/R3K3 w Q - 0 1", "r3k2r/1b4bq/8/8/8/8/7B/R3K2R w KQkq - 0 1", "r3k2r/8/3Q4/8/8/5q2/8/R3K2R b KQkq - 0 1", "2K2r2/4P3/8/8/8/8/8/3k4 w - - 0 1", "8/8/1P2K3/8/2n5/1q6/8/5k2 b - - 0 1", "4k3/1P6/8/8/8/8/K7/8 w - - 0 1", "8/P1k5/K7/8/8/8/8/8 w - - 0 1", "K1k5/8/P7/8/8/8/8/8 w - - 0 1", "8/k1P5/8/1K6/8/8/8/8 w - - 0 1", "8/8/2k5/5q2/5n2/8/5K2/8 b - - 0 1", "r1bq2r1/1pppkppp/1b3n2/pP1PP3/2n5/2P5/P3QPPP/RNB1K2R w KQ a6 0 12", "r3k2r/pppqbppp/3p1n1B/1N2p3/1nB1P3/3P3b/PPPQNPPP/R3K2R w KQkq - 11 10", "4k2r/1pp1n2p/6N1/1K1P2r1/4P3/P5P1/1Pp4P/R7 w k - 0 6", "1Bb3BN/R2Pk2r/1Q5B/4q2R/2bN4/4Q1BK/1p6/1bq1R1rb w - - 0 1", "n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1", "8/PPPk4/8/8/8/8/4Kppp/8 b - - 0 1", "8/2k1p3/3pP3/3P2K1/8/8/8/8 w - - 0 1", "3r4/2p1p3/8/1P1P1P2/3K4/5k2/8/8 b - - 0 1", "8/1p4p1/8/q1PK1P1r/3p1k2/8/4P3/4Q3 b - - 0 1" }; Console.WriteLine($"Running perft (useStackalloc={useStackalloc})"); - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); long timeTotal = 0; for (int i = 0; i < fens.Length; i++) @@ -96,17 +96,17 @@ public static void RunPerft(bool useStackalloc = true) static void TestMoveCreate() { Console.WriteLine("Testing move create"); - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("2rqk2r/1p3p1p/p2p1n2/2PPn3/8/3B1QP1/PR1K1P1p/2B1R3 b k - 1 27"); boardAPI = new(board); - var move = new API.Move("b7b5", boardAPI); + var move = new Move("b7b5", boardAPI); boardAPI.MakeMove(move); - move = new API.Move("c5b6", boardAPI); + move = new Move("c5b6", boardAPI); Assert(move.IsEnPassant, "En passant wrong"); - move = new API.Move("h2h1q", boardAPI); + move = new Move("h2h1q", boardAPI); Assert(move.IsPromotion && move.PromotionPieceType == PieceType.Queen, "Promotion wrong"); - move = new API.Move("e8g8", boardAPI); + move = new Move("e8g8", boardAPI); Assert(move.IsCastles && move.MovePieceType == PieceType.King, "Castles wrong"); } @@ -114,7 +114,7 @@ static void TestBitboards() { Console.WriteLine("Testing Bitboards"); - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("r2q2k1/pp2rppp/3p1n2/1R1Pn3/8/2PB1Q1P/P4PP1/2B2RK1 w - - 7 16"); boardAPI = new(board); @@ -137,7 +137,7 @@ static void TestBitboards() Assert(boardAPI.SquareIsAttackedByOpponent(new Square("c5")), "Square attacked wrong"); Assert(!boardAPI.SquareIsAttackedByOpponent(new Square("c3")), "Square attacked wrong"); Assert(!boardAPI.SquareIsAttackedByOpponent(new Square("h4")), "Square attacked wrong"); - var m1 = new API.Move("b5b7", boardAPI); + var m1 = new Move("b5b7", boardAPI); boardAPI.MakeMove(m1); Assert(boardAPI.SquareIsAttackedByOpponent(new Square("e7")), "Square attacked wrong"); Assert(boardAPI.SquareIsAttackedByOpponent(new Square("b8")), "Square attacked wrong"); @@ -145,7 +145,7 @@ static void TestBitboards() Assert(boardAPI.SquareIsAttackedByOpponent(new Square("h6")), "Square attacked wrong"); Assert(!boardAPI.SquareIsAttackedByOpponent(new Square("a5")), "Square attacked wrong"); Assert(!boardAPI.SquareIsAttackedByOpponent(new Square("b7")), "Square attacked wrong"); - var m2 = new API.Move("f6e4", boardAPI); + var m2 = new Move("f6e4", boardAPI); boardAPI.MakeMove(m2); Assert(boardAPI.SquareIsAttackedByOpponent(new Square("f2")), "Square attacked wrong"); Assert(boardAPI.SquareIsAttackedByOpponent(new Square("c3")), "Square attacked wrong"); @@ -176,32 +176,32 @@ static void TestBitboards() static void CheckTest() { Console.WriteLine("Testing Checks"); - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("r2q1rk1/pp3ppp/3p1n2/3Pn3/8/2PB1Q1P/P4PP1/R1B2RK1 w - - 3 14"); boardAPI = new(board); Assert(!boardAPI.IsInCheck(), "Check wrong"); - API.Move move = new API.Move("d3h7", boardAPI); + Move move = new Move("d3h7", boardAPI); boardAPI.MakeMove(move); Assert(boardAPI.IsInCheck(), "Check wrong"); boardAPI.UndoMove(move); Assert(!boardAPI.IsInCheck(), "Check wrong"); - boardAPI.MakeMove(new API.Move("f3h5", boardAPI)); - boardAPI.MakeMove(new API.Move("f6d7", boardAPI)); + boardAPI.MakeMove(new Move("f3h5", boardAPI)); + boardAPI.MakeMove(new Move("f6d7", boardAPI)); Assert(!boardAPI.IsInCheckmate(), "Checkmate wrong"); - boardAPI.MakeMove(new API.Move("h5h7", boardAPI)); + boardAPI.MakeMove(new Move("h5h7", boardAPI)); Assert(boardAPI.IsInCheckmate(), "Checkmate wrong"); } static void PieceListTest() { Console.WriteLine("Piece Lists Tests"); - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("1q3rk1/P5p1/4p2p/2ppP1N1/5Qb1/1PP5/7P/2R2RK1 w - - 0 28"); boardAPI = new(board); - API.PieceList[] pieceLists = boardAPI.GetAllPieceLists(); + PieceList[] pieceLists = boardAPI.GetAllPieceLists(); int[] counts = { 5, 1, 0, 2, 1, 1, 5, 0, 1, 1, 1, 1 }; for (int i = 0; i < pieceLists.Length; i++) { @@ -216,7 +216,7 @@ static void PieceListTest() Assert(boardAPI.GetPiece(new Square(4, 5)).IsPawn, "Wrong piece"); Assert(!boardAPI.GetPiece(new Square(4, 5)).IsWhite, "Wrong colour"); - API.Move testMove = new("g5e6", boardAPI); + Move testMove = new("g5e6", boardAPI); boardAPI.MakeMove(testMove); Assert(boardAPI.GetPiece(new Square("g5")).IsNull, "Wrong piece"); Assert(boardAPI.GetPiece(new Square("e6")).IsKnight, "Wrong piece"); @@ -232,7 +232,7 @@ static void RepetitionTest() { Console.WriteLine("Repetition test"); string fen = "3k4/8/3K4/8/8/8/8/4Q3 w - - 0 1"; - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition(fen); boardAPI = new(board); @@ -332,9 +332,9 @@ static void RepetitionTest() Make("d8a5"); Assert(boardAPI.IsRepeatedPosition(), "Should be repetition"); - API.Move Make(string name) + Move Make(string name) { - var move = new API.Move(name, boardAPI); + var move = new Move(name, boardAPI); boardAPI.MakeMove(move); return move; } @@ -345,49 +345,49 @@ static void DrawTest() Console.WriteLine("Draw test"); // Repetition test - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("r1r3k1/p1q5/3p2pQ/1p1Pp1N1/2B5/1PP2P2/K1b3P1/7R b - - 2 24"); boardAPI = new(board); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("c7g7", boardAPI)); + boardAPI.MakeMove(new Move("c7g7", boardAPI)); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("h6h4", boardAPI)); + boardAPI.MakeMove(new Move("h6h4", boardAPI)); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("g7c7", boardAPI)); + boardAPI.MakeMove(new Move("g7c7", boardAPI)); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("h4h6", boardAPI)); + boardAPI.MakeMove(new Move("h4h6", boardAPI)); Assert(boardAPI.IsDraw(), "Draw wrong"); - boardAPI.UndoMove(new API.Move("h4h6", boardAPI)); + boardAPI.UndoMove(new Move("h4h6", boardAPI)); Assert(!boardAPI.IsDraw(), "Draw wrong"); // Stalemate test - board = new Chess.Board(); + board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("7K/8/6k1/5q2/8/8/8/8 b - - 0 1"); boardAPI = new(board); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("f5f7", boardAPI)); + boardAPI.MakeMove(new Move("f5f7", boardAPI)); Assert(boardAPI.IsDraw(), "Draw wrong"); // Test stalemate bug when generating captures board.LoadPosition("8/8/3k4/8/8/3K4/4Q3/8 w - - 0 1"); - boardAPI = new API.Board(board); + boardAPI = new Board(board); var captures = boardAPI.GetLegalMoves(capturesOnly: true); Assert(captures.Length == 0, "Wrong capture count"); Assert(!boardAPI.IsInStalemate(), "Stalemate wrong"); // Test stalemate bug when generating captures (non alloc) board.LoadPosition("8/8/3k4/8/8/3K4/4Q3/8 w - - 0 1"); - boardAPI = new API.Board(board); - Span captureSpan = stackalloc API.Move[64]; + boardAPI = new Board(board); + Span captureSpan = stackalloc Move[64]; boardAPI.GetLegalMovesNonAlloc(ref captureSpan, capturesOnly: true); Assert(captureSpan.Length == 0, "Wrong capture count"); Assert(!boardAPI.IsInStalemate(), "Stalemate wrong"); // Insufficient material - board = new Chess.Board(); + board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("7K/3N4/6k1/2n5/8/8/8/8 b - - 0 1"); boardAPI = new(board); Assert(!boardAPI.IsDraw(), "Draw wrong"); - boardAPI.MakeMove(new API.Move("c5d7", boardAPI)); + boardAPI.MakeMove(new Move("c5d7", boardAPI)); Assert(boardAPI.IsDraw(), "Draw wrong"); string[] notInsufficient = @@ -413,17 +413,17 @@ static void DrawTest() foreach (string drawPos in insufficient) { - boardAPI = API.Board.CreateBoardFromFEN(drawPos); + boardAPI = Board.CreateBoardFromFEN(drawPos); Assert(boardAPI.IsDraw(), "Draw wrong, position is insufficient mat"); - boardAPI = API.Board.CreateBoardFromFEN(FenUtility.FlipFen(drawPos)); + boardAPI = Board.CreateBoardFromFEN(FenUtility.FlipFen(drawPos)); Assert(boardAPI.IsDraw(), "Draw wrong, position is insufficient mat"); } foreach (string winnablePos in notInsufficient) { - boardAPI = API.Board.CreateBoardFromFEN(winnablePos); + boardAPI = Board.CreateBoardFromFEN(winnablePos); Assert(!boardAPI.IsDraw(), "Draw wrong, position is winnable"); - boardAPI = API.Board.CreateBoardFromFEN(FenUtility.FlipFen(winnablePos)); + boardAPI = Board.CreateBoardFromFEN(FenUtility.FlipFen(winnablePos)); Assert(!boardAPI.IsDraw(), "Draw wrong, position is winnable"); } } @@ -433,7 +433,7 @@ static void MiscTest() Console.WriteLine("Running Misc Tests"); // Captures - var board = new Chess.Board(); + var board = new ChessEngine.Internal.Board.Board(); board.LoadPosition("1q3rk1/P5p1/4p2p/2ppP1N1/5Qb1/1PP5/7P/2R2RK1 w - - 0 28"); boardAPI = new(board); Assert(boardAPI.IsWhiteToMove, "Colour to move wrong"); @@ -478,7 +478,7 @@ static void MiscTest() board.LoadPosition(startPos); board.MakeMove(MoveUtility.GetMoveFromUCIName("e4e5", board), false); board.MakeMove(MoveUtility.GetMoveFromUCIName("c6e5", board), false); - var b = new Chess.Board(board); + var b = new ChessEngine.Internal.Board.Board(board); boardAPI = new(b); Assert(boardAPI.GameMoveHistory[0].MovePieceType is PieceType.Pawn, "Wrong game move history"); Assert(boardAPI.GameMoveHistory[0].CapturePieceType is PieceType.None, "Wrong game move history"); @@ -516,7 +516,7 @@ static void MiscTest() static void MoveGenTest() { Console.WriteLine("Running move gen tests"); - Chess.Board board = new(); + ChessEngine.Internal.Board.Board board = new(); moveGen = new(); string[] testFens = @@ -534,7 +534,7 @@ static void MoveGenTest() for (int i = 0; i < testFens.Length; i++) { board.LoadPosition(testFens[i]); - boardAPI = new API.Board(board); + boardAPI = new Board(board); ulong result = Search(testDepths[i]); Assert(result == testResults[i], "Movegen test failed"); } @@ -542,7 +542,7 @@ static void MoveGenTest() board.LoadPosition("r2q2k1/pp2rppp/3p1n2/1R1Pn3/8/2PB1Q1P/P4PP1/2B2RK1 w - - 7 16"); boardAPI = new(board); - API.Move m1 = new("f3f6", boardAPI); + Move m1 = new("f3f6", boardAPI); Assert(RecreateOpponentAttackMap() == 18446743649919696896ul, "Wrong attack map"); Assert(boardAPI.GetLegalMoves().Length == 43, "Wrong move count"); Assert(boardAPI.GetLegalMoves(true).Length == 3, "Wrong capture count"); @@ -572,12 +572,12 @@ static void MoveGenTest() Assert(boardAPI.GetLegalMoves().Length == 43, "Wrong move count"); Assert(boardAPI.GetLegalMoves(true).Length == 3, "Wrong capture count"); - Span moveList = stackalloc API.Move[218]; + Span moveList = stackalloc Move[218]; boardAPI.GetLegalMovesNonAlloc(ref moveList); - Span moveListDupe = stackalloc API.Move[218]; + Span moveListDupe = stackalloc Move[218]; boardAPI.GetLegalMovesNonAlloc(ref moveListDupe); Assert(moveList.Length == 43 && moveListDupe.Length == 43, "Move gen wrong"); - Span moveListAtk = stackalloc API.Move[218]; + Span moveListAtk = stackalloc Move[218]; boardAPI.GetLegalMovesNonAlloc(ref moveListAtk, true); Assert(moveListAtk.Length == 3, "Move gen wrong"); Assert(RecreateOpponentAttackMap() == 18446743649919696896ul, "Wrong attack map"); @@ -623,7 +623,7 @@ static ulong Search(int depth) static ulong SearchStackalloc(int depth) { - Span moves = stackalloc API.Move[128]; + Span moves = stackalloc Move[128]; boardAPI.GetLegalMovesNonAlloc(ref moves); if (depth == 1) @@ -670,7 +670,7 @@ public class SearchTest3 { - API.Board board; + Board board; int numCaptures; int numChecks; int numMates; @@ -679,11 +679,11 @@ public class SearchTest3 public void Run() { Console.WriteLine("Running misc search test"); - Chess.Board b = new(); + ChessEngine.Internal.Board.Board b = new(); b.LoadPosition("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - "); - board = new API.Board(b); + board = new Board(b); var sw = System.Diagnostics.Stopwatch.StartNew(); - Search(4, API.Move.NullMove); + Search(4, Move.NullMove); sw.Stop(); Console.WriteLine("Test3 time: " + sw.ElapsedMilliseconds + " ms"); bool passed = nodes == 4085603 && numCaptures == 757163 && numChecks == 25523 && numMates == 43; @@ -692,10 +692,10 @@ public void Run() } - void Search(int depth, API.Move prevMove) + void Search(int depth, Move prevMove) { - Span moveSpan = stackalloc API.Move[256]; + Span moveSpan = stackalloc Move[256]; board.GetLegalMovesNonAlloc(ref moveSpan); if (depth == 0) @@ -731,7 +731,7 @@ void Search(int depth, API.Move prevMove) public class SearchTest2 { - API.Board board; + Board board; int numSkips; int numCalls; int numMates; @@ -741,9 +741,9 @@ public class SearchTest2 public void Run() { Console.WriteLine("Running misc search test"); - Chess.Board b = new(); + ChessEngine.Internal.Board.Board b = new(); b.LoadPosition("8/2b5/2kp4/2p2K2/7P/1p3RP1/2n3N1/8 w - - 0 1"); - board = new API.Board(b); + board = new Board(b); var sw = System.Diagnostics.Stopwatch.StartNew(); Search(7, -10000, 10000); sw.Stop(); @@ -795,10 +795,10 @@ int Search(int plyRemaining, int alpha, int beta, bool isQ = false) } - API.Move[] moves; + Move[] moves; if (numCalls % 3 == 0 || numCalls % 7 == 0) { - Span moveSpan = stackalloc API.Move[256]; + Span moveSpan = stackalloc Move[256]; board.GetLegalMovesNonAlloc(ref moveSpan, isQ); // (don't actually care about allocations here, just testing the func) moves = moveSpan.ToArray(); @@ -842,7 +842,7 @@ int Search(int plyRemaining, int alpha, int beta, bool isQ = false) public class SearchTest { - API.Board board; + Board board; bool useStackalloc; int numLeafNodes; int numCalls; @@ -852,9 +852,9 @@ public void Run(bool useStackalloc) { this.useStackalloc = useStackalloc; Console.WriteLine("Running misc search test | stackalloc = " + useStackalloc); - Chess.Board b = new(); + ChessEngine.Internal.Board.Board b = new(); b.LoadPosition("2rqk2r/5p1p/p2p1n2/1pPPn3/8/3B1QP1/PR1K1P1p/2B1R3 w k b6 0 28"); - board = new API.Board(b); + board = new Board(b); Search(4); Assert(miscSumTest == 101146355, "Misc search test failed"); @@ -897,10 +897,10 @@ void Search(int plyRemaining) } - API.Move[] moves; + Move[] moves; if (useStackalloc) { - Span moveSpan = stackalloc API.Move[256]; + Span moveSpan = stackalloc Move[256]; board.GetLegalMovesNonAlloc(ref moveSpan); moves = moveSpan.ToArray(); // (don't actually care about allocations here, just testing the func) } diff --git a/Chess-Challenge/src/Framework/Application/Helpers/UIHelper.cs b/ChessChallenge/src/Framework/Application/Helpers/UIHelper.cs similarity index 96% rename from Chess-Challenge/src/Framework/Application/Helpers/UIHelper.cs rename to ChessChallenge/src/Framework/Application/Helpers/UIHelper.cs index d83ce4ac3..1fad64f48 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/UIHelper.cs +++ b/ChessChallenge/src/Framework/Application/Helpers/UIHelper.cs @@ -1,9 +1,9 @@ -using Raylib_cs; -using System; +using System; using System.Numerics; -using static ChessChallenge.Application.FileHelper; +using Raylib_cs; +using static ChessChallenge.Framework.Application.Helpers.FileHelper; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Helpers { public static class UIHelper { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/Warmer.cs b/ChessChallenge/src/Framework/Application/Helpers/Warmer.cs similarity index 69% rename from Chess-Challenge/src/Framework/Application/Helpers/Warmer.cs rename to ChessChallenge/src/Framework/Application/Helpers/Warmer.cs index 564dd2a1c..6b051872b 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/Warmer.cs +++ b/ChessChallenge/src/Framework/Application/Helpers/Warmer.cs @@ -1,13 +1,13 @@ -using ChessChallenge.API; +using ChessEngine; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Helpers { public static class Warmer { public static void Warm() { - Chess.Board b = new(); + ChessEngine.Internal.Board.Board b = new(); b.LoadStartPosition(); Board board = new Board(b); Move[] moves = board.GetLegalMoves(); diff --git a/Chess-Challenge/src/Framework/Application/Players/ChessPlayer.cs b/ChessChallenge/src/Framework/Application/Players/ChessPlayer.cs similarity index 85% rename from Chess-Challenge/src/Framework/Application/Players/ChessPlayer.cs rename to ChessChallenge/src/Framework/Application/Players/ChessPlayer.cs index b3406984f..9d6a4382a 100644 --- a/Chess-Challenge/src/Framework/Application/Players/ChessPlayer.cs +++ b/ChessChallenge/src/Framework/Application/Players/ChessPlayer.cs @@ -1,7 +1,9 @@ -using ChessChallenge.API; -using System; +using System; +using ChessChallenge.Framework.Application.Core; +using ChessEngine; +using Move = ChessEngine.Internal.Board.Move; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Players { public class ChessPlayer { @@ -57,7 +59,7 @@ public int TimeRemainingMs } } - public void SubscribeToMoveChosenEventIfHuman(Action action) + public void SubscribeToMoveChosenEventIfHuman(Action action) { if (Human != null) { diff --git a/Chess-Challenge/src/Framework/Application/Players/HumanPlayer.cs b/ChessChallenge/src/Framework/Application/Players/HumanPlayer.cs similarity index 92% rename from Chess-Challenge/src/Framework/Application/Players/HumanPlayer.cs rename to ChessChallenge/src/Framework/Application/Players/HumanPlayer.cs index b8396a069..5af37c5cb 100644 --- a/Chess-Challenge/src/Framework/Application/Players/HumanPlayer.cs +++ b/ChessChallenge/src/Framework/Application/Players/HumanPlayer.cs @@ -1,8 +1,11 @@ -using ChessChallenge.Chess; +using System.Numerics; +using ChessChallenge.Framework.Application.Core; +using ChessChallenge.Framework.Application.UI; +using ChessEngine.Internal.Board; +using ChessEngine.Internal.MoveGeneration; using Raylib_cs; -using System.Numerics; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.Players { public class HumanPlayer { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/Token Counter/Microsoft.CodeAnalysis.CSharp.dll b/ChessChallenge/src/Framework/Application/TokenCounting/Microsoft.CodeAnalysis.CSharp.dll similarity index 100% rename from Chess-Challenge/src/Framework/Application/Helpers/Token Counter/Microsoft.CodeAnalysis.CSharp.dll rename to ChessChallenge/src/Framework/Application/TokenCounting/Microsoft.CodeAnalysis.CSharp.dll diff --git a/Chess-Challenge/src/Framework/Application/Helpers/Token Counter/Microsoft.CodeAnalysis.dll b/ChessChallenge/src/Framework/Application/TokenCounting/Microsoft.CodeAnalysis.dll similarity index 100% rename from Chess-Challenge/src/Framework/Application/Helpers/Token Counter/Microsoft.CodeAnalysis.dll rename to ChessChallenge/src/Framework/Application/TokenCounting/Microsoft.CodeAnalysis.dll diff --git a/Chess-Challenge/src/Framework/Application/Helpers/Token Counter/TokenCounter.cs b/ChessChallenge/src/Framework/Application/TokenCounting/TokenCounter.cs similarity index 96% rename from Chess-Challenge/src/Framework/Application/Helpers/Token Counter/TokenCounter.cs rename to ChessChallenge/src/Framework/Application/TokenCounting/TokenCounter.cs index 2e1fa82bc..0693def9d 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/Token Counter/TokenCounter.cs +++ b/ChessChallenge/src/Framework/Application/TokenCounting/TokenCounter.cs @@ -1,11 +1,11 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; +using System; using System.Collections.Generic; using System.Linq; -using System; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.TokenCounting { public static class TokenCounter { diff --git a/Chess-Challenge/src/Framework/Application/UI/BoardTheme.cs b/ChessChallenge/src/Framework/Application/UI/BoardTheme.cs similarity index 95% rename from Chess-Challenge/src/Framework/Application/UI/BoardTheme.cs rename to ChessChallenge/src/Framework/Application/UI/BoardTheme.cs index 40eb0cb16..a74530ba7 100644 --- a/Chess-Challenge/src/Framework/Application/UI/BoardTheme.cs +++ b/ChessChallenge/src/Framework/Application/UI/BoardTheme.cs @@ -1,6 +1,6 @@ using Raylib_cs; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.UI { public class BoardTheme { diff --git a/Chess-Challenge/src/Framework/Application/UI/BoardUI.cs b/ChessChallenge/src/Framework/Application/UI/BoardUI.cs similarity index 97% rename from Chess-Challenge/src/Framework/Application/UI/BoardUI.cs rename to ChessChallenge/src/Framework/Application/UI/BoardUI.cs index 9ca8b048c..06285281f 100644 --- a/Chess-Challenge/src/Framework/Application/UI/BoardUI.cs +++ b/ChessChallenge/src/Framework/Application/UI/BoardUI.cs @@ -1,13 +1,18 @@ -using ChessChallenge.Chess; -using Raylib_cs; -using System; +using System; using System.Collections.Generic; -using System.Numerics; using System.IO; -using static ChessChallenge.Application.UIHelper; -using ChessChallenge.Application.APIHelpers; +using System.Numerics; +using ChessChallenge.Framework.Application.Core; +using ChessChallenge.Framework.Application.Helpers; +using ChessEngine.Helpers; +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration; +using ChessEngine.Internal.MoveGeneration.Bitboards; +using Raylib_cs; +using static ChessChallenge.Framework.Application.Helpers.UIHelper; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.UI { public class BoardUI { diff --git a/Chess-Challenge/src/Framework/Application/UI/BotBrainCapacityUI.cs b/ChessChallenge/src/Framework/Application/UI/BotBrainCapacityUI.cs similarity index 93% rename from Chess-Challenge/src/Framework/Application/UI/BotBrainCapacityUI.cs rename to ChessChallenge/src/Framework/Application/UI/BotBrainCapacityUI.cs index 50f25af75..9f3507c1c 100644 --- a/Chess-Challenge/src/Framework/Application/UI/BotBrainCapacityUI.cs +++ b/ChessChallenge/src/Framework/Application/UI/BotBrainCapacityUI.cs @@ -1,6 +1,7 @@ -using Raylib_cs; +using ChessChallenge.Framework.Application.Helpers; +using Raylib_cs; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.UI { public static class BotBrainCapacityUI { diff --git a/Chess-Challenge/src/Framework/Application/UI/MatchStatsUI.cs b/ChessChallenge/src/Framework/Application/UI/MatchStatsUI.cs similarity index 89% rename from Chess-Challenge/src/Framework/Application/UI/MatchStatsUI.cs rename to ChessChallenge/src/Framework/Application/UI/MatchStatsUI.cs index fc22e4645..c9b4caaae 100644 --- a/Chess-Challenge/src/Framework/Application/UI/MatchStatsUI.cs +++ b/ChessChallenge/src/Framework/Application/UI/MatchStatsUI.cs @@ -1,8 +1,9 @@ -using Raylib_cs; -using System.Numerics; -using System; +using System.Numerics; +using ChessChallenge.Framework.Application.Core; +using ChessChallenge.Framework.Application.Helpers; +using Raylib_cs; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.UI { public static class MatchStatsUI { diff --git a/Chess-Challenge/src/Framework/Application/UI/MenuUI.cs b/ChessChallenge/src/Framework/Application/UI/MenuUI.cs similarity index 94% rename from Chess-Challenge/src/Framework/Application/UI/MenuUI.cs rename to ChessChallenge/src/Framework/Application/UI/MenuUI.cs index 1e39fcf3f..b0234fca6 100644 --- a/Chess-Challenge/src/Framework/Application/UI/MenuUI.cs +++ b/ChessChallenge/src/Framework/Application/UI/MenuUI.cs @@ -1,9 +1,11 @@ -using Raylib_cs; -using System.Numerics; -using System; +using System; using System.IO; +using System.Numerics; +using ChessChallenge.Framework.Application.Core; +using ChessChallenge.Framework.Application.Helpers; +using Raylib_cs; -namespace ChessChallenge.Application +namespace ChessChallenge.Framework.Application.UI { public static class MenuUI { @@ -45,7 +47,7 @@ public static void DrawButtons(ChallengeController controller) } if (NextButtonInRow("Rules & Help", ref buttonPos, spacing, buttonSize)) { - FileHelper.OpenUrl("https://github.com/SebLague/Chess-Challenge"); + FileHelper.OpenUrl("https://github.com/SebLague/ChessChallenge"); } if (NextButtonInRow("Documentation", ref buttonPos, spacing, buttonSize)) { diff --git a/Chess-Challenge/src/API/BitboardHelper.cs b/ChessEngine/BitboardHelper.cs similarity index 98% rename from Chess-Challenge/src/API/BitboardHelper.cs rename to ChessEngine/BitboardHelper.cs index ae1039797..8a3fd1ebf 100644 --- a/Chess-Challenge/src/API/BitboardHelper.cs +++ b/ChessEngine/BitboardHelper.cs @@ -1,9 +1,9 @@ +using ChessEngine.Helpers; +using ChessEngine.Internal.MoveGeneration.Bitboards; +using ChessEngine.Internal.MoveGeneration.Magics; -namespace ChessChallenge.API +namespace ChessEngine { - using ChessChallenge.Application.APIHelpers; - using ChessChallenge.Chess; - /// /// Helper class for working with bitboards. /// Bitboards are represented with the ulong type (unsigned 64 bit integer). diff --git a/Chess-Challenge/src/API/Board.cs b/ChessEngine/Board.cs similarity index 94% rename from Chess-Challenge/src/API/Board.cs rename to ChessEngine/Board.cs index b85d1c383..ec2bf90c5 100644 --- a/Chess-Challenge/src/API/Board.cs +++ b/ChessEngine/Board.cs @@ -1,15 +1,14 @@ -namespace ChessChallenge.API -{ - using ChessChallenge.Application.APIHelpers; - using ChessChallenge.Chess; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; +using System.Text; +using ChessEngine.Helpers; +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.Result; +namespace ChessEngine +{ public sealed class Board { - readonly Chess.Board board; + readonly Internal.Board.Board board; readonly APIMoveGen moveGen; readonly RepetitionTable repetitionTable; @@ -17,7 +16,7 @@ public sealed class Board readonly PieceList[] validPieceLists; readonly Move[] movesDest; - Move[] cachedLegalMoves; + Move[] cachedLegalMoves; bool hasCachedMoves; Move[] cachedLegalCaptureMoves; bool hasCachedCaptureMoves; @@ -29,17 +28,17 @@ public sealed class Board /// Create a new board. Note: this should not be used in the challenge, /// use the board provided in the Think method instead. /// - public Board(Chess.Board boardSource) + public Board(Internal.Board.Board boardSource) { // Clone board and create game move history - board = new Chess.Board(); + board = new Internal.Board.Board(); board.LoadPosition(boardSource.StartPositionInfo); GameMoveHistory = new Move[boardSource.AllGameMoves.Count]; repetitionTable = new(); for (int i = 0; i < boardSource.AllGameMoves.Count; i ++) { - Chess.Move move = boardSource.AllGameMoves[i]; + Internal.Board.Move move = boardSource.AllGameMoves[i]; int movePieceType = PieceHelper.PieceType(board.Square[move.StartSquareIndex]); int capturePieceType = move.IsEnPassant ? PieceHelper.Pawn : PieceHelper.PieceType(board.Square[move.TargetSquareIndex]); GameMoveHistory[i] = new Move(move, movePieceType, capturePieceType); @@ -80,7 +79,7 @@ public void MakeMove(Move move) if (!move.IsNull) { OnPositionChanged(); - board.MakeMove(new Chess.Move(move.RawValue), inSearch: true); + board.MakeMove(new Internal.Board.Move(move.RawValue), inSearch: true); repetitionTable.Push(ZobristKey, move.IsCapture || move.MovePieceType == PieceType.Pawn); depth++; @@ -95,7 +94,7 @@ public void UndoMove(Move move) if (!move.IsNull) { repetitionTable.TryPop(); - board.UndoMove(new Chess.Move(move.RawValue), inSearch: true); + board.UndoMove(new Internal.Board.Move(move.RawValue), inSearch: true); OnPositionChanged(); depth--; } @@ -258,7 +257,7 @@ public bool IsDraw() /// public Square GetKingSquare(bool white) { - int colIndex = white ? Chess.Board.WhiteIndex : Chess.Board.BlackIndex; + int colIndex = white ? Internal.Board.Board.WhiteIndex : Internal.Board.Board.BlackIndex; return new Square(board.KingSquare[colIndex]); } @@ -315,11 +314,11 @@ public ulong GetPieceBitboard(PieceType pieceType, bool white) /// /// 64-bit number where each bit that is set to 1 represents a square that contains any type of white piece. /// - public ulong WhitePiecesBitboard => board.colourBitboards[Chess.Board.WhiteIndex]; + public ulong WhitePiecesBitboard => board.colourBitboards[Internal.Board.Board.WhiteIndex]; /// /// 64-bit number where each bit that is set to 1 represents a square that contains any type of black piece. /// - public ulong BlackPiecesBitboard => board.colourBitboards[Chess.Board.BlackIndex]; + public ulong BlackPiecesBitboard => board.colourBitboards[Internal.Board.Board.BlackIndex]; /// /// 64-bit number where each bit that is set to 1 represents a @@ -442,7 +441,7 @@ static char GetPieceSymbol(Piece piece) /// public static Board CreateBoardFromFEN(string fen) { - Chess.Board boardCore = new Chess.Board(); + Internal.Board.Board boardCore = new Internal.Board.Board(); boardCore.LoadPosition(fen); return new Board(boardCore); } diff --git a/ChessEngine/ChessEngine.csproj b/ChessEngine/ChessEngine.csproj new file mode 100644 index 000000000..3a6353295 --- /dev/null +++ b/ChessEngine/ChessEngine.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/APIMoveGen.cs b/ChessEngine/Helpers/APIMoveGen.cs similarity index 91% rename from Chess-Challenge/src/Framework/Application/Helpers/API Helpers/APIMoveGen.cs rename to ChessEngine/Helpers/APIMoveGen.cs index 2cbe29799..e1f40ba90 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/APIMoveGen.cs +++ b/ChessEngine/Helpers/APIMoveGen.cs @@ -1,8 +1,11 @@ -using ChessChallenge.Chess; -using System; -using static ChessChallenge.Chess.PrecomputedMoveData; - -namespace ChessChallenge.Application.APIHelpers +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration; +using ChessEngine.Internal.MoveGeneration.Bitboards; +using ChessEngine.Internal.MoveGeneration.Magics; +using static ChessEngine.Internal.MoveGeneration.PrecomputedMoveData; + +namespace ChessEngine.Helpers { public class APIMoveGen @@ -34,7 +37,7 @@ public class APIMoveGen ulong opponentSlidingAttackMap; bool generateNonCapture; - Board board; + Internal.Board.Board board; int currMoveIndex; ulong enemyPieces; @@ -49,7 +52,7 @@ public class APIMoveGen public APIMoveGen() { - board = new Board(); + board = new Internal.Board.Board(); } public bool IsInitialized => hasInitializedCurrentPosition; @@ -60,15 +63,15 @@ public void NotifyPositionChanged() hasInitializedCurrentPosition = false; } - public ulong GetOpponentAttackMap(Board board) + public ulong GetOpponentAttackMap(Internal.Board.Board board) { Init(board); return opponentAttackMap; } - public bool NoLegalMovesInPosition(Board board) + public bool NoLegalMovesInPosition(Internal.Board.Board board) { - Span moves = stackalloc API.Move[128]; + Span moves = stackalloc Move[128]; generateNonCapture = true; Init(board); GenerateKingMoves(moves); @@ -89,7 +92,7 @@ public bool NoLegalMovesInPosition(Board board) // Generates list of legal moves in current position. // Quiet moves (non captures) can optionally be excluded. This is used in quiescence search. - public void GenerateMoves(ref Span moves, Board board, bool includeQuietMoves = true) + public void GenerateMoves(ref Span moves, Internal.Board.Board board, bool includeQuietMoves = true) { generateNonCapture = includeQuietMoves; @@ -114,7 +117,7 @@ public bool InCheck() return inCheck; } - public void Init(Board board) + public void Init(Internal.Board.Board board) { this.board = board; currMoveIndex = 0; @@ -157,24 +160,24 @@ public void Init(Board board) } - API.Move CreateAPIMove(int startSquare, int targetSquare, int flag) + Move CreateAPIMove(int startSquare, int targetSquare, int flag) { int movePieceType = PieceHelper.PieceType(board.Square[startSquare]); return CreateAPIMove(startSquare, targetSquare, flag, movePieceType); } - API.Move CreateAPIMove(int startSquare, int targetSquare, int flag, int movePieceType) + Move CreateAPIMove(int startSquare, int targetSquare, int flag, int movePieceType) { int capturePieceType = PieceHelper.PieceType(board.Square[targetSquare]); - if (flag == Move.EnPassantCaptureFlag) + if (flag == Internal.Board.Move.EnPassantCaptureFlag) { capturePieceType = PieceHelper.Pawn; } - API.Move apiMove = new(new Move(startSquare, targetSquare, flag), movePieceType, capturePieceType); + Move apiMove = new(new Internal.Board.Move(startSquare, targetSquare, flag), movePieceType, capturePieceType); return apiMove; } - void GenerateKingMoves(Span moves) + void GenerateKingMoves(Span moves) { ulong legalMask = ~(opponentAttackMap | friendlyPieces); ulong kingMoves = Bits.KingMoves[friendlyKingSquare] & legalMask & moveTypeMask; @@ -194,7 +197,7 @@ void GenerateKingMoves(Span moves) if ((castleMask & castleBlockers) == 0) { int targetSquare = board.IsWhiteToMove ? BoardHelper.g1 : BoardHelper.g8; - moves[currMoveIndex++] = CreateAPIMove(friendlyKingSquare, targetSquare, Move.CastleFlag, PieceHelper.King); + moves[currMoveIndex++] = CreateAPIMove(friendlyKingSquare, targetSquare, Internal.Board.Move.CastleFlag, PieceHelper.King); } } if (board.currentGameState.HasQueensideCastleRight(board.IsWhiteToMove)) @@ -204,13 +207,13 @@ void GenerateKingMoves(Span moves) if ((castleMask & castleBlockers) == 0 && (castleBlockMask & board.allPiecesBitboard) == 0) { int targetSquare = board.IsWhiteToMove ? BoardHelper.c1 : BoardHelper.c8; - moves[currMoveIndex++] = CreateAPIMove(friendlyKingSquare, targetSquare, Move.CastleFlag, PieceHelper.King); + moves[currMoveIndex++] = CreateAPIMove(friendlyKingSquare, targetSquare, Internal.Board.Move.CastleFlag, PieceHelper.King); } } } } - void GenerateSlidingMoves(Span moves, bool exitEarly = false) + void GenerateSlidingMoves(Span moves, bool exitEarly = false) { // Limit movement to empty or enemy squares, and must block check if king is in check. ulong moveMask = emptyOrEnemySquares & checkRayBitmask & moveTypeMask; @@ -273,7 +276,7 @@ void GenerateSlidingMoves(Span moves, bool exitEarly = false) } - void GenerateKnightMoves(Span moves) + void GenerateKnightMoves(Span moves) { int friendlyKnightPiece = PieceHelper.MakePiece(PieceHelper.Knight, board.MoveColour); // bitboard of all non-pinned knights @@ -293,7 +296,7 @@ void GenerateKnightMoves(Span moves) } } - void GeneratePawnMoves(Span moves) + void GeneratePawnMoves(Span moves) { int pushDir = board.IsWhiteToMove ? 1 : -1; int pushOffset = pushDir * 8; @@ -345,7 +348,7 @@ void GeneratePawnMoves(Span moves) int startSquare = targetSquare - pushOffset * 2; if (!IsPinned(startSquare) || alignMask[startSquare, friendlyKingSquare] == alignMask[targetSquare, friendlyKingSquare]) { - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PawnTwoUpFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PawnTwoUpFlag, PieceHelper.Pawn); } } } @@ -431,7 +434,7 @@ void GeneratePawnMoves(Span moves) { if (!InCheckAfterEnPassant(startSquare, targetSquare, capturedPawnSquare)) { - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.EnPassantCaptureFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.EnPassantCaptureFlag, PieceHelper.Pawn); } } } @@ -439,21 +442,21 @@ void GeneratePawnMoves(Span moves) } } - void GeneratePromotions(Span moves, int startSquare, int targetSquare) + void GeneratePromotions(Span moves, int startSquare, int targetSquare) { - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PromoteToQueenFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PromoteToQueenFlag, PieceHelper.Pawn); // Don't generate non-queen promotions in q-search if (generateNonCapture) { if (promotionsToGenerate == MoveGenerator.PromotionMode.All) { - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PromoteToKnightFlag, PieceHelper.Pawn); - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PromoteToRookFlag, PieceHelper.Pawn); - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PromoteToBishopFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PromoteToKnightFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PromoteToRookFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PromoteToBishopFlag, PieceHelper.Pawn); } else if (promotionsToGenerate == MoveGenerator.PromotionMode.QueenAndKnight) { - moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Move.PromoteToKnightFlag, PieceHelper.Pawn); + moves[currMoveIndex++] = CreateAPIMove(startSquare, targetSquare, Internal.Board.Move.PromoteToKnightFlag, PieceHelper.Pawn); } } } diff --git a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/BitboardDebugState.cs b/ChessEngine/Helpers/BitboardDebugState.cs similarity index 79% rename from Chess-Challenge/src/Framework/Application/Helpers/API Helpers/BitboardDebugState.cs rename to ChessEngine/Helpers/BitboardDebugState.cs index 73248daeb..d33b4b3dc 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/BitboardDebugState.cs +++ b/ChessEngine/Helpers/BitboardDebugState.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Application.APIHelpers +namespace ChessEngine.Helpers { public static class BitboardDebugState { diff --git a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/MoveHelper.cs b/ChessEngine/Helpers/MoveHelper.cs similarity index 67% rename from Chess-Challenge/src/Framework/Application/Helpers/API Helpers/MoveHelper.cs rename to ChessEngine/Helpers/MoveHelper.cs index e9cf7ebd2..18bcd55fb 100644 --- a/Chess-Challenge/src/Framework/Application/Helpers/API Helpers/MoveHelper.cs +++ b/ChessEngine/Helpers/MoveHelper.cs @@ -1,13 +1,11 @@ -using ChessChallenge.Chess; -using System; -using ChessChallenge.API; +using ChessEngine.Internal.Helpers; -namespace ChessChallenge.Application.APIHelpers +namespace ChessEngine.Helpers { public class MoveHelper { - public static (Chess.Move move, PieceType pieceType, PieceType captureType) CreateMoveFromName(string moveNameUCI, API.Board board) + public static (Internal.Board.Move move, PieceType pieceType, PieceType captureType) CreateMoveFromName(string moveNameUCI, Board board) { int indexStart = BoardHelper.SquareIndexFromName(moveNameUCI[0] + "" + moveNameUCI[1]); int indexTarget = BoardHelper.SquareIndexFromName(moveNameUCI[2] + "" + moveNameUCI[3]); @@ -30,7 +28,7 @@ public static (Chess.Move move, PieceType pieceType, PieceType captureType) Crea PieceType capturedPieceType = board.GetPiece(targetSquare).PieceType; // Figure out move flag - int flag = Chess.Move.NoFlag; + int flag = Internal.Board.Move.NoFlag; if (movedPieceType == PieceType.Pawn) { @@ -38,10 +36,10 @@ public static (Chess.Move move, PieceType pieceType, PieceType captureType) Crea { flag = promotePieceType switch { - PieceType.Queen => Chess.Move.PromoteToQueenFlag, - PieceType.Rook => Chess.Move.PromoteToRookFlag, - PieceType.Knight => Chess.Move.PromoteToKnightFlag, - PieceType.Bishop => Chess.Move.PromoteToBishopFlag, + PieceType.Queen => Internal.Board.Move.PromoteToQueenFlag, + PieceType.Rook => Internal.Board.Move.PromoteToRookFlag, + PieceType.Knight => Internal.Board.Move.PromoteToKnightFlag, + PieceType.Bishop => Internal.Board.Move.PromoteToBishopFlag, _ => 0 }; } @@ -49,12 +47,12 @@ public static (Chess.Move move, PieceType pieceType, PieceType captureType) Crea { if (Math.Abs(targetSquare.Rank - startSquare.Rank) == 2) { - flag = Chess.Move.PawnTwoUpFlag; + flag = Internal.Board.Move.PawnTwoUpFlag; } // En-passant else if (startSquare.File != targetSquare.File && board.GetPiece(targetSquare).IsNull) { - flag = Chess.Move.EnPassantCaptureFlag; + flag = Internal.Board.Move.EnPassantCaptureFlag; } } } @@ -62,11 +60,11 @@ public static (Chess.Move move, PieceType pieceType, PieceType captureType) Crea { if (Math.Abs(startSquare.File - targetSquare.File) > 1) { - flag = Chess.Move.CastleFlag; + flag = Internal.Board.Move.CastleFlag; } } - Chess.Move coreMove = new Chess.Move(startSquare.Index, targetSquare.Index, flag); + Internal.Board.Move coreMove = new Internal.Board.Move(startSquare.Index, targetSquare.Index, flag); return (coreMove, movedPieceType, capturedPieceType); } diff --git a/Chess-Challenge/src/API/IChessBot.cs b/ChessEngine/IChessBot.cs similarity index 73% rename from Chess-Challenge/src/API/IChessBot.cs rename to ChessEngine/IChessBot.cs index 05fb71360..7996acec1 100644 --- a/Chess-Challenge/src/API/IChessBot.cs +++ b/ChessEngine/IChessBot.cs @@ -1,5 +1,4 @@ - -namespace ChessChallenge.API +namespace ChessEngine { public interface IChessBot { diff --git a/Chess-Challenge/src/Framework/Chess/Board/Board.cs b/ChessEngine/Internal/Board/Board.cs similarity index 99% rename from Chess-Challenge/src/Framework/Chess/Board/Board.cs rename to ChessEngine/Internal/Board/Board.cs index 9fd4c1f3b..5704554be 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/Board.cs +++ b/ChessEngine/Internal/Board/Board.cs @@ -1,6 +1,8 @@ -using System.Collections.Generic; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration.Bitboards; +using ChessEngine.Internal.MoveGeneration.Magics; -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { // Represents the current state of the board during a game. // The state includes things such as: positions of all pieces, side to move, diff --git a/Chess-Challenge/src/Framework/Chess/Board/Coord.cs b/ChessEngine/Internal/Board/Coord.cs similarity index 95% rename from Chess-Challenge/src/Framework/Chess/Board/Coord.cs rename to ChessEngine/Internal/Board/Coord.cs index 0fc66581e..61e125178 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/Coord.cs +++ b/ChessEngine/Internal/Board/Coord.cs @@ -1,5 +1,6 @@ -using System; -namespace ChessChallenge.Chess +using ChessEngine.Internal.Helpers; + +namespace ChessEngine.Internal.Board { // Structure for representing squares on the chess board as file/rank integer pairs. // (0, 0) = a1, (7, 7) = h8. diff --git a/Chess-Challenge/src/Framework/Chess/Board/GameState.cs b/ChessEngine/Internal/Board/GameState.cs similarity index 96% rename from Chess-Challenge/src/Framework/Chess/Board/GameState.cs rename to ChessEngine/Internal/Board/GameState.cs index 23619d471..b23b2535b 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/GameState.cs +++ b/ChessEngine/Internal/Board/GameState.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { public readonly struct GameState { diff --git a/Chess-Challenge/src/Framework/Chess/Board/Move.cs b/ChessEngine/Internal/Board/Move.cs similarity index 98% rename from Chess-Challenge/src/Framework/Chess/Board/Move.cs rename to ChessEngine/Internal/Board/Move.cs index 1be192b7f..37c1b6cf6 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/Move.cs +++ b/ChessEngine/Internal/Board/Move.cs @@ -6,7 +6,7 @@ The format is as follows (ffffttttttssssss) Bits 6-11: target square index Bits 12-15: flag (promotion type, etc) */ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { public readonly struct Move { diff --git a/Chess-Challenge/src/Framework/Chess/Board/PieceHelper.cs b/ChessEngine/Internal/Board/PieceHelper.cs similarity index 98% rename from Chess-Challenge/src/Framework/Chess/Board/PieceHelper.cs rename to ChessEngine/Internal/Board/PieceHelper.cs index b4b807f23..ed4a338db 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/PieceHelper.cs +++ b/ChessEngine/Internal/Board/PieceHelper.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { // Contains definitions for each piece type (represented as integers), // as well as various helper functions for dealing with pieces. diff --git a/Chess-Challenge/src/Framework/Chess/Board/PieceList.cs b/ChessEngine/Internal/Board/PieceList.cs similarity index 97% rename from Chess-Challenge/src/Framework/Chess/Board/PieceList.cs rename to ChessEngine/Internal/Board/PieceList.cs index f0f918adb..2552454a8 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/PieceList.cs +++ b/ChessEngine/Internal/Board/PieceList.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { public class PieceList { diff --git a/Chess-Challenge/src/Framework/Chess/Board/RepetitionTable.cs b/ChessEngine/Internal/Board/RepetitionTable.cs similarity index 93% rename from Chess-Challenge/src/Framework/Chess/Board/RepetitionTable.cs rename to ChessEngine/Internal/Board/RepetitionTable.cs index b317f068f..cd5e5de48 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/RepetitionTable.cs +++ b/ChessEngine/Internal/Board/RepetitionTable.cs @@ -1,7 +1,4 @@ -using System; -using System.Linq; - -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { public class RepetitionTable { @@ -16,7 +13,7 @@ public RepetitionTable() startIndices = new int[size]; } - public void Init(Board board) + public void Init(Internal.Board.Board board) { ulong[] initialHashes = board.RepetitionPositionHistory.Reverse().ToArray(); count = initialHashes.Length; diff --git a/Chess-Challenge/src/Framework/Chess/Board/Zobrist.cs b/ChessEngine/Internal/Board/Zobrist.cs similarity index 96% rename from Chess-Challenge/src/Framework/Chess/Board/Zobrist.cs rename to ChessEngine/Internal/Board/Zobrist.cs index 079d74f17..0ae332eca 100644 --- a/Chess-Challenge/src/Framework/Chess/Board/Zobrist.cs +++ b/ChessEngine/Internal/Board/Zobrist.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Board { // Helper class for the calculation of zobrist hash. // This is a single 64bit value that (non-uniquely) represents the current state of the game. @@ -52,7 +52,7 @@ static Zobrist() // Calculate zobrist key from current board position. // NOTE: this function is slow and should only be used when the board is initially set up from fen. // During search, the key should be updated incrementally instead. - public static ulong CalculateZobristKey(Board board) + public static ulong CalculateZobristKey(Internal.Board.Board board) { ulong zobristKey = 0; diff --git a/Chess-Challenge/src/Framework/Chess/Helpers/BoardHelper.cs b/ChessEngine/Internal/Helpers/BoardHelper.cs similarity index 97% rename from Chess-Challenge/src/Framework/Chess/Helpers/BoardHelper.cs rename to ChessEngine/Internal/Helpers/BoardHelper.cs index fa3444fae..eb3287798 100644 --- a/Chess-Challenge/src/Framework/Chess/Helpers/BoardHelper.cs +++ b/ChessEngine/Internal/Helpers/BoardHelper.cs @@ -1,4 +1,6 @@ -namespace ChessChallenge.Chess +using ChessEngine.Internal.Board; + +namespace ChessEngine.Internal.Helpers { public static class BoardHelper { diff --git a/Chess-Challenge/src/Framework/Chess/Helpers/FenUtility.cs b/ChessEngine/Internal/Helpers/FenUtility.cs similarity index 96% rename from Chess-Challenge/src/Framework/Chess/Helpers/FenUtility.cs rename to ChessEngine/Internal/Helpers/FenUtility.cs index ce07710be..aad37a6e5 100644 --- a/Chess-Challenge/src/Framework/Chess/Helpers/FenUtility.cs +++ b/ChessEngine/Internal/Helpers/FenUtility.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; +using ChessEngine.Internal.Board; -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Helpers { // Helper class for dealing with FEN strings public static class FenUtility @@ -22,7 +21,7 @@ public static PositionInfo PositionFromFen(string fen) /// When alwaysIncludeEPSquare is true the en passant square will be included /// in the fen string even if no enemy pawn is in a position to capture it. /// - public static string CurrentFen(Board board, bool alwaysIncludeEPSquare = true) + public static string CurrentFen(Internal.Board.Board board, bool alwaysIncludeEPSquare = true) { string fen = ""; for (int rank = 7; rank >= 0; rank--) @@ -124,7 +123,7 @@ public static string CurrentFen(Board board, bool alwaysIncludeEPSquare = true) return fen; } - static bool EnPassantCanBeCaptured(int epFileIndex, int epRankIndex, Board board) + static bool EnPassantCanBeCaptured(int epFileIndex, int epRankIndex, Internal.Board.Board board) { Coord captureFromA = new Coord(epFileIndex - 1, epRankIndex + (board.IsWhiteToMove ? -1 : 1)); Coord captureFromB = new Coord(epFileIndex + 1, epRankIndex + (board.IsWhiteToMove ? -1 : 1)); @@ -141,7 +140,7 @@ bool CanCapture(Coord from) bool isPawnOnSquare = board.Square[from.SquareIndex] == friendlyPawn; if (from.IsValidSquare() && isPawnOnSquare) { - Move move = new Move(from.SquareIndex, epCaptureSquare, Move.EnPassantCaptureFlag); + Board.Move move = new Board.Move(from.SquareIndex, epCaptureSquare, Board.Move.EnPassantCaptureFlag); board.MakeMove(move); board.MakeNullMove(); bool wasLegalMove = !board.CalculateInCheckState(); diff --git a/Chess-Challenge/src/Framework/Chess/Helpers/MoveUtility.cs b/ChessEngine/Internal/Helpers/MoveUtility.cs similarity index 86% rename from Chess-Challenge/src/Framework/Chess/Helpers/MoveUtility.cs rename to ChessEngine/Internal/Helpers/MoveUtility.cs index fa64ffb7c..30441dca4 100644 --- a/Chess-Challenge/src/Framework/Chess/Helpers/MoveUtility.cs +++ b/ChessEngine/Internal/Helpers/MoveUtility.cs @@ -1,4 +1,7 @@ -namespace ChessChallenge.Chess +using ChessEngine.Internal.Board; +using ChessEngine.Internal.MoveGeneration; + +namespace ChessEngine.Internal.Helpers { // Helper class for converting between various move representations: // UCI: move represented by string, e.g. "e2e4" @@ -9,7 +12,7 @@ public static class MoveUtility // Converts a moveName into internal move representation // Name is expected in UCI format: "e2e4" // Promotions can be written with or without equals sign, for example: "e7e8=q" or "e7e8q" - public static Move GetMoveFromUCIName(string moveName, Board board) + public static Board.Move GetMoveFromUCIName(string moveName, Internal.Board.Board board) { int startSquare = BoardHelper.SquareIndexFromName(moveName.Substring(0, 2)); @@ -20,7 +23,7 @@ public static Move GetMoveFromUCIName(string moveName, Board board) Coord targetCoord = new Coord(targetSquare); // Figure out move flag - int flag = Move.NoFlag; + int flag = Board.Move.NoFlag; if (movedPieceType == PieceHelper.Pawn) { @@ -29,38 +32,38 @@ public static Move GetMoveFromUCIName(string moveName, Board board) { flag = moveName[^1] switch { - 'q' => Move.PromoteToQueenFlag, - 'r' => Move.PromoteToRookFlag, - 'n' => Move.PromoteToKnightFlag, - 'b' => Move.PromoteToBishopFlag, - _ => Move.NoFlag + 'q' => Board.Move.PromoteToQueenFlag, + 'r' => Board.Move.PromoteToRookFlag, + 'n' => Board.Move.PromoteToKnightFlag, + 'b' => Board.Move.PromoteToBishopFlag, + _ => Board.Move.NoFlag }; } // Double pawn push else if (System.Math.Abs(targetCoord.rankIndex - startCoord.rankIndex) == 2) { - flag = Move.PawnTwoUpFlag; + flag = Board.Move.PawnTwoUpFlag; } // En-passant else if (startCoord.fileIndex != targetCoord.fileIndex && board.Square[targetSquare] == PieceHelper.None) { - flag = Move.EnPassantCaptureFlag; + flag = Board.Move.EnPassantCaptureFlag; } } else if (movedPieceType == PieceHelper.King) { if (System.Math.Abs(startCoord.fileIndex - targetCoord.fileIndex) > 1) { - flag = Move.CastleFlag; + flag = Board.Move.CastleFlag; } } - return new Move(startSquare, targetSquare, flag); + return new Board.Move(startSquare, targetSquare, flag); } // Get name of move in UCI format // Examples: "e2e4", "e7e8q" - public static string GetMoveNameUCI(Move move) + public static string GetMoveNameUCI(Board.Move move) { if (move.IsNull) { @@ -73,16 +76,16 @@ public static string GetMoveNameUCI(Move move) { switch (move.MoveFlag) { - case Move.PromoteToRookFlag: + case Board.Move.PromoteToRookFlag: moveName += "r"; break; - case Move.PromoteToKnightFlag: + case Board.Move.PromoteToKnightFlag: moveName += "n"; break; - case Move.PromoteToBishopFlag: + case Board.Move.PromoteToBishopFlag: moveName += "b"; break; - case Move.PromoteToQueenFlag: + case Board.Move.PromoteToQueenFlag: moveName += "q"; break; } @@ -93,7 +96,7 @@ public static string GetMoveNameUCI(Move move) // Get name of move in Standard Algebraic Notation (SAN) // Examples: "e4", "Bxf7+", "O-O", "Rh8#", "Nfd2" // Note, the move must not yet have been made on the board - public static string GetMoveNameSAN(Move move, Board board) + public static string GetMoveNameSAN(Internal.Board.Move move, Internal.Board.Board board) { if (move.IsNull) { @@ -102,7 +105,7 @@ public static string GetMoveNameSAN(Move move, Board board) int movePieceType = PieceHelper.PieceType(board.Square[move.StartSquareIndex]); int capturedPieceType = PieceHelper.PieceType(board.Square[move.TargetSquareIndex]); - if (move.MoveFlag == Move.CastleFlag) + if (move.MoveFlag == Board.Move.CastleFlag) { int delta = move.TargetSquareIndex - move.StartSquareIndex; if (delta == 2) @@ -123,16 +126,16 @@ public static string GetMoveNameSAN(Move move, Board board) { var allMoves = moveGen.GenerateMoves(board); - foreach (Move altMove in allMoves) + foreach (var altMove in allMoves) { if (altMove.StartSquareIndex != move.StartSquareIndex && altMove.TargetSquareIndex == move.TargetSquareIndex) { // if moving to same square from different square if (PieceHelper.PieceType(board.Square[altMove.StartSquareIndex]) == movePieceType) { // same piece type - int fromFileIndex = BoardHelper.FileIndex(move.StartSquareIndex); + int fromFileIndex = BoardHelper.FileIndex(altMove.StartSquareIndex); int alternateFromFileIndex = BoardHelper.FileIndex(altMove.StartSquareIndex); - int fromRankIndex = BoardHelper.RankIndex(move.StartSquareIndex); + int fromRankIndex = BoardHelper.RankIndex(altMove.StartSquareIndex); int alternateFromRankIndex = BoardHelper.RankIndex(altMove.StartSquareIndex); if (fromFileIndex != alternateFromFileIndex) @@ -161,7 +164,7 @@ public static string GetMoveNameSAN(Move move, Board board) } else { // check if capturing ep - if (move.MoveFlag == Move.EnPassantCaptureFlag) + if (move.MoveFlag == Board.Move.EnPassantCaptureFlag) { moveNotation += BoardHelper.fileNames[BoardHelper.FileIndex(move.StartSquareIndex)] + "x"; } @@ -215,7 +218,7 @@ string GetSymbolFromPieceType(int pieceType) } } - public static Move GetMoveFromSAN(Board board, string algebraicMove) + public static Board.Move GetMoveFromSAN(Internal.Board.Board board, string algebraicMove) { MoveGenerator moveGenerator = new MoveGenerator(); @@ -223,9 +226,9 @@ public static Move GetMoveFromSAN(Board board, string algebraicMove) algebraicMove = algebraicMove.Replace("+", "").Replace("#", "").Replace("x", "").Replace("-", ""); var allMoves = moveGenerator.GenerateMoves(board); - Move move = new Move(); + Board.Move move = new Board.Move(); - foreach (Move moveToTest in allMoves) + foreach (Board.Move moveToTest in allMoves) { move = moveToTest; diff --git a/Chess-Challenge/src/Framework/Chess/Helpers/PGNCreator.cs b/ChessEngine/Internal/Helpers/PGNCreator.cs similarity index 74% rename from Chess-Challenge/src/Framework/Chess/Helpers/PGNCreator.cs rename to ChessEngine/Internal/Helpers/PGNCreator.cs index d9f954130..dfbdcdb5e 100644 --- a/Chess-Challenge/src/Framework/Chess/Helpers/PGNCreator.cs +++ b/ChessEngine/Internal/Helpers/PGNCreator.cs @@ -1,28 +1,28 @@ - -using System.Text; +using System.Text; +using ChessEngine.Internal.Result; -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Helpers { public static class PGNCreator { - public static string CreatePGN(Move[] moves) + public static string CreatePGN(Internal.Board.Move[] moves) { return CreatePGN(moves, GameResult.InProgress, FenUtility.StartPositionFEN); } - public static string CreatePGN(Board board, GameResult result, string whiteName = "", string blackName = "") + public static string CreatePGN(Internal.Board.Board board, GameResult result, string whiteName = "", string blackName = "") { return CreatePGN(board.AllGameMoves.ToArray(), result, board.GameStartFen, whiteName, blackName); } - public static string CreatePGN(Move[] moves, GameResult result, string startFen, string whiteName = "", string blackName = "") + public static string CreatePGN(Internal.Board.Move[] moves, GameResult result, string startFen, string whiteName = "", string blackName = "") { startFen = startFen.Replace("\n", "").Replace("\r", ""); StringBuilder pgn = new(); - Board board = new Board(); + Internal.Board.Board board = new Internal.Board.Board(); board.LoadPosition(startFen); // Headers if (!string.IsNullOrEmpty(whiteName)) diff --git a/Chess-Challenge/src/Framework/Chess/Helpers/PGNLoader.cs b/ChessEngine/Internal/Helpers/PGNLoader.cs similarity index 78% rename from Chess-Challenge/src/Framework/Chess/Helpers/PGNLoader.cs rename to ChessEngine/Internal/Helpers/PGNLoader.cs index 950fecccd..37fb636ce 100644 --- a/Chess-Challenge/src/Framework/Chess/Helpers/PGNLoader.cs +++ b/ChessEngine/Internal/Helpers/PGNLoader.cs @@ -1,11 +1,9 @@ -using System.Collections.Generic; - -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Helpers { public static class PGNLoader { - public static Move[] MovesFromPGN(string pgn, int maxPlyCount = int.MaxValue) + public static Internal.Board.Move[] MovesFromPGN(string pgn, int maxPlyCount = int.MaxValue) { List algebraicMoves = new List(); @@ -35,15 +33,15 @@ public static Move[] MovesFromPGN(string pgn, int maxPlyCount = int.MaxValue) return MovesFromAlgebraic(algebraicMoves.ToArray()); } - static Move[] MovesFromAlgebraic(string[] algebraicMoves) + static Internal.Board.Move[] MovesFromAlgebraic(string[] algebraicMoves) { - Board board = new Board(); + Internal.Board.Board board = new Internal.Board.Board(); board.LoadStartPosition(); - var moves = new List(); + var moves = new List(); for (int i = 0; i < algebraicMoves.Length; i++) { - Move move = MoveUtility.GetMoveFromSAN(board, algebraicMoves[i].Trim()); + Internal.Board.Move move = MoveUtility.GetMoveFromSAN(board, algebraicMoves[i].Trim()); if (move.IsNull) { // move is illegal; discard and return moves up to this point string pgn = ""; diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/BitBoardUtility.cs b/ChessEngine/Internal/MoveGeneration/Bitboards/BitBoardUtility.cs similarity index 97% rename from Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/BitBoardUtility.cs rename to ChessEngine/Internal/MoveGeneration/Bitboards/BitBoardUtility.cs index 5e4e91f4b..cf03d6bfc 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/BitBoardUtility.cs +++ b/ChessEngine/Internal/MoveGeneration/Bitboards/BitBoardUtility.cs @@ -1,7 +1,7 @@ -namespace ChessChallenge.Chess -{ - using System.Numerics; +using System.Numerics; +namespace ChessEngine.Internal.MoveGeneration.Bitboards +{ public static class BitBoardUtility { diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/Bits.cs b/ChessEngine/Internal/MoveGeneration/Bitboards/Bits.cs similarity index 98% rename from Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/Bits.cs rename to ChessEngine/Internal/MoveGeneration/Bitboards/Bits.cs index 5a3cffd51..ef629c0c5 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/Bitboards/Bits.cs +++ b/ChessEngine/Internal/MoveGeneration/Bitboards/Bits.cs @@ -1,6 +1,7 @@ +using ChessEngine.Internal.Helpers; using static System.Math; -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.MoveGeneration.Bitboards { // A collection of precomputed bitboards for use during movegen, search, etc. public static class Bits diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/Magic.cs b/ChessEngine/Internal/MoveGeneration/Magics/Magic.cs similarity index 98% rename from Chess-Challenge/src/Framework/Chess/Move Generation/Magics/Magic.cs rename to ChessEngine/Internal/MoveGeneration/Magics/Magic.cs index f5eb16fc0..257a5a6d1 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/Magic.cs +++ b/ChessEngine/Internal/MoveGeneration/Magics/Magic.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.MoveGeneration.Magics { using static PrecomputedMagics; diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/MagicHelper.cs b/ChessEngine/Internal/MoveGeneration/Magics/MagicHelper.cs similarity index 94% rename from Chess-Challenge/src/Framework/Chess/Move Generation/Magics/MagicHelper.cs rename to ChessEngine/Internal/MoveGeneration/Magics/MagicHelper.cs index 217f5d3b8..74ca64516 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/MagicHelper.cs +++ b/ChessEngine/Internal/MoveGeneration/Magics/MagicHelper.cs @@ -1,6 +1,8 @@ -using System.Collections.Generic; +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration.Bitboards; -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.MoveGeneration.Magics { public static class MagicHelper { diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/PrecomputedMagics.cs b/ChessEngine/Internal/MoveGeneration/Magics/PrecomputedMagics.cs similarity index 98% rename from Chess-Challenge/src/Framework/Chess/Move Generation/Magics/PrecomputedMagics.cs rename to ChessEngine/Internal/MoveGeneration/Magics/PrecomputedMagics.cs index 605b4ae15..566928dae 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/Magics/PrecomputedMagics.cs +++ b/ChessEngine/Internal/MoveGeneration/Magics/PrecomputedMagics.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.MoveGeneration.Magics { public static class PrecomputedMagics { diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/MoveGenerator.cs b/ChessEngine/Internal/MoveGeneration/MoveGenerator.cs similarity index 87% rename from Chess-Challenge/src/Framework/Chess/Move Generation/MoveGenerator.cs rename to ChessEngine/Internal/MoveGeneration/MoveGenerator.cs index af6e8976c..4cb0dd44b 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/MoveGenerator.cs +++ b/ChessEngine/Internal/MoveGeneration/MoveGenerator.cs @@ -1,6 +1,10 @@ -namespace ChessChallenge.Chess +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration.Bitboards; +using ChessEngine.Internal.MoveGeneration.Magics; + +namespace ChessEngine.Internal.MoveGeneration { - using System; using static PrecomputedMoveData; public class MoveGenerator @@ -34,7 +38,7 @@ public enum PromotionMode { All, QueenOnly, QueenAndKnight } ulong opponentSlidingAttackMap; bool generateQuietMoves; - Board board; + Internal.Board.Board board; int currMoveIndex; ulong enemyPieces; @@ -46,15 +50,15 @@ public enum PromotionMode { All, QueenOnly, QueenAndKnight } // Otherwise it will have 1s everywhere. ulong moveTypeMask; - public System.Span GenerateMoves(Board board, bool includeQuietMoves = true) + public System.Span GenerateMoves(Internal.Board.Board board, bool includeQuietMoves = true) { - System.Span moves = new Move[MaxMoves]; + System.Span moves = new Internal.Board.Move[MaxMoves]; return GenerateMoves(board, moves, includeQuietMoves); } // Generates list of legal moves in current position. // Quiet moves (non captures) can optionally be excluded. This is used in quiescence search. - public System.Span GenerateMoves(Board board, System.Span moves, bool includeQuietMoves = true) + public System.Span GenerateMoves(Internal.Board.Board board, System.Span moves, bool includeQuietMoves = true) { this.board = board; generateQuietMoves = includeQuietMoves; @@ -108,14 +112,14 @@ void Init() CalculateAttackData(); } - void GenerateKingMoves(System.Span moves) + void GenerateKingMoves(System.Span moves) { ulong legalMask = ~(opponentAttackMap | friendlyPieces); ulong kingMoves = Bits.KingMoves[friendlyKingSquare] & legalMask & moveTypeMask; while (kingMoves != 0) { int targetSquare = BitBoardUtility.PopLSB(ref kingMoves); - moves[currMoveIndex++] = new Move(friendlyKingSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(friendlyKingSquare, targetSquare); } // Castling @@ -128,7 +132,7 @@ void GenerateKingMoves(System.Span moves) if ((castleMask & castleBlockers) == 0) { int targetSquare = board.IsWhiteToMove ? BoardHelper.g1 : BoardHelper.g8; - moves[currMoveIndex++] = new Move(friendlyKingSquare, targetSquare, Move.CastleFlag); + moves[currMoveIndex++] = new Internal.Board.Move(friendlyKingSquare, targetSquare, Internal.Board.Move.CastleFlag); } } if (board.currentGameState.HasQueensideCastleRight(board.IsWhiteToMove)) @@ -138,13 +142,13 @@ void GenerateKingMoves(System.Span moves) if ((castleMask & castleBlockers) == 0 && (castleBlockMask & board.allPiecesBitboard) == 0) { int targetSquare = board.IsWhiteToMove ? BoardHelper.c1 : BoardHelper.c8; - moves[currMoveIndex++] = new Move(friendlyKingSquare, targetSquare, Move.CastleFlag); + moves[currMoveIndex++] = new Internal.Board.Move(friendlyKingSquare, targetSquare, Internal.Board.Move.CastleFlag); } } } } - void GenerateSlidingMoves(System.Span moves) + void GenerateSlidingMoves(System.Span moves) { // Limit movement to empty or enemy squares, and must block check if king is in check. ulong moveMask = emptyOrEnemySquares & checkRayBitmask & moveTypeMask; @@ -174,7 +178,7 @@ void GenerateSlidingMoves(System.Span moves) while (moveSquares != 0) { int targetSquare = BitBoardUtility.PopLSB(ref moveSquares); - moves[currMoveIndex++] = new Move(startSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare); } } @@ -193,13 +197,13 @@ void GenerateSlidingMoves(System.Span moves) while (moveSquares != 0) { int targetSquare = BitBoardUtility.PopLSB(ref moveSquares); - moves[currMoveIndex++] = new Move(startSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare); } } } - void GenerateKnightMoves(System.Span moves) + void GenerateKnightMoves(System.Span moves) { int friendlyKnightPiece = PieceHelper.MakePiece(PieceHelper.Knight, board.MoveColour); // bitboard of all non-pinned knights @@ -214,12 +218,12 @@ void GenerateKnightMoves(System.Span moves) while (moveSquares != 0) { int targetSquare = BitBoardUtility.PopLSB(ref moveSquares); - moves[currMoveIndex++] = new Move(knightSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(knightSquare, targetSquare); } } } - void GeneratePawnMoves(System.Span moves) + void GeneratePawnMoves(System.Span moves) { int pushDir = board.IsWhiteToMove ? 1 : -1; int pushOffset = pushDir * 8; @@ -257,7 +261,7 @@ void GeneratePawnMoves(System.Span moves) int startSquare = targetSquare - pushOffset; if (!IsPinned(startSquare) || alignMask[startSquare, friendlyKingSquare] == alignMask[targetSquare, friendlyKingSquare]) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare); } } @@ -271,7 +275,7 @@ void GeneratePawnMoves(System.Span moves) int startSquare = targetSquare - pushOffset * 2; if (!IsPinned(startSquare) || alignMask[startSquare, friendlyKingSquare] == alignMask[targetSquare, friendlyKingSquare]) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PawnTwoUpFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PawnTwoUpFlag); } } } @@ -284,7 +288,7 @@ void GeneratePawnMoves(System.Span moves) if (!IsPinned(startSquare) || alignMask[startSquare, friendlyKingSquare] == alignMask[targetSquare, friendlyKingSquare]) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare); } } @@ -295,7 +299,7 @@ void GeneratePawnMoves(System.Span moves) if (!IsPinned(startSquare) || alignMask[startSquare, friendlyKingSquare] == alignMask[targetSquare, friendlyKingSquare]) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare); } } @@ -354,7 +358,7 @@ void GeneratePawnMoves(System.Span moves) { if (!InCheckAfterEnPassant(startSquare, targetSquare, capturedPawnSquare)) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.EnPassantCaptureFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.EnPassantCaptureFlag); } } } @@ -362,21 +366,21 @@ void GeneratePawnMoves(System.Span moves) } } - void GeneratePromotions(int startSquare, int targetSquare, Span moves) + void GeneratePromotions(int startSquare, int targetSquare, Span moves) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PromoteToQueenFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PromoteToQueenFlag); // Don't generate non-queen promotions in q-search if (generateQuietMoves) { if (promotionsToGenerate == MoveGenerator.PromotionMode.All) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PromoteToKnightFlag); - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PromoteToRookFlag); - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PromoteToBishopFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PromoteToKnightFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PromoteToRookFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PromoteToBishopFlag); } else if (promotionsToGenerate == MoveGenerator.PromotionMode.QueenAndKnight) { - moves[currMoveIndex++] = new Move(startSquare, targetSquare, Move.PromoteToKnightFlag); + moves[currMoveIndex++] = new Internal.Board.Move(startSquare, targetSquare, Internal.Board.Move.PromoteToKnightFlag); } } } @@ -514,7 +518,7 @@ void CalculateAttackData() } // Pawn attacks - PieceList opponentPawns = board.pawns[enemyIndex]; + Internal.Board.PieceList opponentPawns = board.pawns[enemyIndex]; opponentPawnAttackMap = 0; ulong opponentPawnsBoard = board.pieceBitboards[PieceHelper.MakePiece(PieceHelper.Pawn, board.OpponentColour)]; diff --git a/Chess-Challenge/src/Framework/Chess/Move Generation/PrecomputedMoveData.cs b/ChessEngine/Internal/MoveGeneration/PrecomputedMoveData.cs similarity index 95% rename from Chess-Challenge/src/Framework/Chess/Move Generation/PrecomputedMoveData.cs rename to ChessEngine/Internal/MoveGeneration/PrecomputedMoveData.cs index c8975a92c..94bc1214d 100644 --- a/Chess-Challenge/src/Framework/Chess/Move Generation/PrecomputedMoveData.cs +++ b/ChessEngine/Internal/MoveGeneration/PrecomputedMoveData.cs @@ -1,6 +1,8 @@ -namespace ChessChallenge.Chess +using ChessEngine.Internal.Board; +using ChessEngine.Internal.Helpers; + +namespace ChessEngine.Internal.MoveGeneration { - using System.Collections.Generic; using static System.Math; public static class PrecomputedMoveData @@ -163,12 +165,12 @@ static PrecomputedMoveData() if (y < 7) { pawnCapturesWhite.Add(squareIndex + 7); - pawnAttackBitboards[squareIndex][Board.WhiteIndex] |= 1ul << (squareIndex + 7); + pawnAttackBitboards[squareIndex][Internal.Board.Board.WhiteIndex] |= 1ul << (squareIndex + 7); } if (y > 0) { pawnCapturesBlack.Add(squareIndex - 9); - pawnAttackBitboards[squareIndex][Board.BlackIndex] |= 1ul << (squareIndex - 9); + pawnAttackBitboards[squareIndex][Internal.Board.Board.BlackIndex] |= 1ul << (squareIndex - 9); } } if (x < 7) @@ -176,12 +178,12 @@ static PrecomputedMoveData() if (y < 7) { pawnCapturesWhite.Add(squareIndex + 9); - pawnAttackBitboards[squareIndex][Board.WhiteIndex] |= 1ul << (squareIndex + 9); + pawnAttackBitboards[squareIndex][Internal.Board.Board.WhiteIndex] |= 1ul << (squareIndex + 9); } if (y > 0) { pawnCapturesBlack.Add(squareIndex - 7); - pawnAttackBitboards[squareIndex][Board.BlackIndex] |= 1ul << (squareIndex - 7); + pawnAttackBitboards[squareIndex][Internal.Board.Board.BlackIndex] |= 1ul << (squareIndex - 7); } } pawnAttacksWhite[squareIndex] = pawnCapturesWhite.ToArray(); diff --git a/Chess-Challenge/src/Framework/Chess/Result/Arbiter.cs b/ChessEngine/Internal/Result/Arbiter.cs similarity index 79% rename from Chess-Challenge/src/Framework/Chess/Result/Arbiter.cs rename to ChessEngine/Internal/Result/Arbiter.cs index c2cd01b39..f1879b5aa 100644 --- a/Chess-Challenge/src/Framework/Chess/Result/Arbiter.cs +++ b/ChessEngine/Internal/Result/Arbiter.cs @@ -1,7 +1,8 @@ -namespace ChessChallenge.Chess -{ - using System.Linq; +using ChessEngine.Internal.Helpers; +using ChessEngine.Internal.MoveGeneration; +namespace ChessEngine.Internal.Result +{ public static class Arbiter { public static bool IsDrawResult(GameResult result) @@ -26,7 +27,7 @@ public static bool IsBlackWinsResult(GameResult result) } - public static GameResult GetGameState(Board board) + public static GameResult GetGameState(Internal.Board.Board board) { MoveGenerator moveGenerator = new MoveGenerator(); var moves = moveGenerator.GenerateMoves(board); @@ -48,7 +49,7 @@ public static GameResult GetGameState(Board board) } // Threefold repetition - int repCount = board.RepetitionPositionHistory.Count((x => x == board.currentGameState.zobristKey)); + int repCount = board.RepetitionPositionHistory.Count(x => x == board.currentGameState.zobristKey); if (repCount == 3) { return GameResult.Repetition; @@ -63,10 +64,10 @@ public static GameResult GetGameState(Board board) } // Test for insufficient material (Note: not all cases are implemented) - public static bool InsufficentMaterial(Board board) + public static bool InsufficentMaterial(Internal.Board.Board board) { // Can't have insufficient material with pawns on the board - if (board.pawns[Board.WhiteIndex].Count > 0 || board.pawns[Board.BlackIndex].Count > 0) + if (board.pawns[Board.Board.WhiteIndex].Count > 0 || board.pawns[Board.Board.BlackIndex].Count > 0) { return false; } @@ -78,10 +79,10 @@ public static bool InsufficentMaterial(Board board) } // If no pawns, queens, or rooks on the board, then consider knight and bishop cases - int numWhiteBishops = board.bishops[Board.WhiteIndex].Count; - int numBlackBishops = board.bishops[Board.BlackIndex].Count; - int numWhiteKnights = board.knights[Board.WhiteIndex].Count; - int numBlackKnights = board.knights[Board.BlackIndex].Count; + int numWhiteBishops = board.bishops[Board.Board.WhiteIndex].Count; + int numBlackBishops = board.bishops[Board.Board.BlackIndex].Count; + int numWhiteKnights = board.knights[Board.Board.WhiteIndex].Count; + int numBlackKnights = board.knights[Board.Board.BlackIndex].Count; int numWhiteMinors = numWhiteBishops + numWhiteKnights; int numBlackMinors = numBlackBishops + numBlackKnights; int numMinors = numWhiteMinors + numBlackMinors; @@ -95,8 +96,8 @@ public static bool InsufficentMaterial(Board board) // Bishop vs bishop: is insufficient when bishops are same colour complex if (numMinors == 2 && numWhiteBishops == 1 && numBlackBishops == 1) { - bool whiteBishopIsLightSquare = BoardHelper.LightSquare(board.bishops[Board.WhiteIndex][0]); - bool blackBishopIsLightSquare = BoardHelper.LightSquare(board.bishops[Board.BlackIndex][0]); + bool whiteBishopIsLightSquare = BoardHelper.LightSquare(board.bishops[Board.Board.WhiteIndex][0]); + bool blackBishopIsLightSquare = BoardHelper.LightSquare(board.bishops[Board.Board.BlackIndex][0]); return whiteBishopIsLightSquare == blackBishopIsLightSquare; } diff --git a/Chess-Challenge/src/Framework/Chess/Result/GameResult.cs b/ChessEngine/Internal/Result/GameResult.cs similarity index 89% rename from Chess-Challenge/src/Framework/Chess/Result/GameResult.cs rename to ChessEngine/Internal/Result/GameResult.cs index e8a50fe5b..fd2d91fbf 100644 --- a/Chess-Challenge/src/Framework/Chess/Result/GameResult.cs +++ b/ChessEngine/Internal/Result/GameResult.cs @@ -1,4 +1,4 @@ -namespace ChessChallenge.Chess +namespace ChessEngine.Internal.Result { public enum GameResult { diff --git a/Chess-Challenge/src/API/Move.cs b/ChessEngine/Move.cs similarity index 82% rename from Chess-Challenge/src/API/Move.cs rename to ChessEngine/Move.cs index 936d31942..5697bd88c 100644 --- a/Chess-Challenge/src/API/Move.cs +++ b/ChessEngine/Move.cs @@ -1,7 +1,6 @@ -using ChessChallenge.Chess; -using System; +using ChessEngine.Internal.Helpers; -namespace ChessChallenge.API +namespace ChessEngine { public readonly struct Move : IEquatable { @@ -11,15 +10,15 @@ namespace ChessChallenge.API public PieceType CapturePieceType => (PieceType)(pieceTypeData >> 3); public PieceType PromotionPieceType => (PieceType)move.PromotionPieceType; public bool IsCapture => (pieceTypeData >> 3) != 0; - public bool IsEnPassant => move.MoveFlag == Chess.Move.EnPassantCaptureFlag; + public bool IsEnPassant => move.MoveFlag == Internal.Board.Move.EnPassantCaptureFlag; public bool IsPromotion => move.IsPromotion; - public bool IsCastles => move.MoveFlag == Chess.Move.CastleFlag; + public bool IsCastles => move.MoveFlag == Internal.Board.Move.CastleFlag; public bool IsNull => move.IsNull; public ushort RawValue => move.Value; public static readonly Move NullMove = new(); - readonly Chess.Move move; + readonly Internal.Board.Move move; readonly ushort pieceTypeData; /// @@ -28,7 +27,7 @@ namespace ChessChallenge.API /// public Move() { - move = Chess.Move.NullMove; + move = Internal.Board.Move.NullMove; pieceTypeData = 0; } @@ -38,7 +37,7 @@ public Move() /// public Move(string moveName, Board board) { - var data = Application.APIHelpers.MoveHelper.CreateMoveFromName(moveName, board); + var data = Helpers.MoveHelper.CreateMoveFromName(moveName, board); move = data.move; pieceTypeData = (ushort)((int)data.pieceType | ((int)data.captureType << 3)); @@ -47,7 +46,7 @@ public Move(string moveName, Board board) /// /// Internal move constructor. Do not use. /// - public Move(Chess.Move move, int movePieceType, int capturePieceType) + public Move(Internal.Board.Move move, int movePieceType, int capturePieceType) { this.move = move; pieceTypeData = (ushort)(movePieceType | (capturePieceType << 3)); diff --git a/Chess-Challenge/src/API/Piece.cs b/ChessEngine/Piece.cs similarity index 97% rename from Chess-Challenge/src/API/Piece.cs rename to ChessEngine/Piece.cs index ae6813cef..60fd94a98 100644 --- a/Chess-Challenge/src/API/Piece.cs +++ b/ChessEngine/Piece.cs @@ -1,6 +1,4 @@ -using System; - -namespace ChessChallenge.API +namespace ChessEngine { public readonly struct Piece : IEquatable { diff --git a/Chess-Challenge/src/API/PieceList.cs b/ChessEngine/PieceList.cs similarity index 78% rename from Chess-Challenge/src/API/PieceList.cs rename to ChessEngine/PieceList.cs index fce28bbaf..8a08f1cae 100644 --- a/Chess-Challenge/src/API/PieceList.cs +++ b/ChessEngine/PieceList.cs @@ -1,7 +1,7 @@ using System.Collections; -using System.Collections.Generic; +using ChessEngine.Internal.Board; -namespace ChessChallenge.API +namespace ChessEngine { /// /// A special list for storing pieces of a particular type and colour @@ -13,19 +13,19 @@ public sealed class PieceList : IEnumerable public readonly PieceType TypeOfPieceInList; public Piece GetPiece(int index) => this[index]; - readonly Chess.PieceList list; + readonly Internal.Board.PieceList list; readonly Board board; /// /// Piece List constructor (you shouldn't be creating your own piece lists in /// this challenge, but rather accessing the existing lists from the board). /// - public PieceList(Chess.PieceList list, Board board, int piece) + public PieceList(Internal.Board.PieceList list, Board board, int piece) { this.board = board; this.list = list; - TypeOfPieceInList = (PieceType)Chess.PieceHelper.PieceType(piece); - IsWhitePieceList = Chess.PieceHelper.IsWhite(piece); + TypeOfPieceInList = (PieceType)PieceHelper.PieceType(piece); + IsWhitePieceList = PieceHelper.IsWhite(piece); } diff --git a/ChessEngine/PieceType.cs b/ChessEngine/PieceType.cs new file mode 100644 index 000000000..4552233bc --- /dev/null +++ b/ChessEngine/PieceType.cs @@ -0,0 +1,12 @@ +namespace ChessEngine; + +public enum PieceType +{ + None, // 0 + Pawn, // 1 + Knight, // 2 + Bishop, // 3 + Rook, // 4 + Queen, // 5 + King // 6 +} \ No newline at end of file diff --git a/Chess-Challenge/src/API/Square.cs b/ChessEngine/Square.cs similarity index 78% rename from Chess-Challenge/src/API/Square.cs rename to ChessEngine/Square.cs index d4459c16b..2d57d1841 100644 --- a/Chess-Challenge/src/API/Square.cs +++ b/ChessEngine/Square.cs @@ -1,34 +1,34 @@ -using System; +using ChessEngine.Internal.Helpers; -namespace ChessChallenge.API +namespace ChessEngine { public readonly struct Square : IEquatable { /// /// Value from 0 to 7 representing files 'a' to 'h' /// - public int File => Chess.BoardHelper.FileIndex(Index); + public int File => BoardHelper.FileIndex(Index); /// /// Value from 0 to 7 representing ranks '1' to '8' /// - public int Rank => Chess.BoardHelper.RankIndex(Index); + public int Rank => BoardHelper.RankIndex(Index); /// /// Value from 0 to 63. The values map to the board like so: - /// 0 – 7 : a1 – h1, 8 – 15 : a2 – h2, ..., 56 – 63 : a8 – h8 + /// 0 � 7 : a1 � h1, 8 � 15 : a2 � h2, ..., 56 � 63 : a8 � h8 /// public readonly int Index; /// /// The algebraic name of the square, e.g. "e4" /// - public string Name => Chess.BoardHelper.SquareNameFromIndex(Index); + public string Name => BoardHelper.SquareNameFromIndex(Index); /// /// Create a square from its algebraic name, e.g. "e4" /// public Square(string name) { - Index = Chess.BoardHelper.SquareIndexFromName(name); + Index = BoardHelper.SquareIndexFromName(name); } /// @@ -44,7 +44,7 @@ public Square(int index) /// public Square(int file, int rank) { - Index = Chess.BoardHelper.IndexFromCoord(file, rank); + Index = BoardHelper.IndexFromCoord(file, rank); } public override string ToString() diff --git a/Chess-Challenge/src/API/Timer.cs b/ChessEngine/Timer.cs similarity index 97% rename from Chess-Challenge/src/API/Timer.cs rename to ChessEngine/Timer.cs index 884cf257d..f3d974542 100644 --- a/Chess-Challenge/src/API/Timer.cs +++ b/ChessEngine/Timer.cs @@ -1,6 +1,4 @@ -using System; - -namespace ChessChallenge.API +namespace ChessEngine { public sealed class Timer { diff --git a/protos.json.json b/protos.json.json new file mode 100644 index 000000000..5fea66fab --- /dev/null +++ b/protos.json.json @@ -0,0 +1,13 @@ +{ + "protocols" : { + "lldp" : { }, + "vrrp" : { + "version" : "v3", + "vrrp-v3" : { + "ipv4-checksum-with-pseudoheader" : [ null ] + }, + "mac-address-mode" : "physical", + "alarm-logs-soak-time" : 3600 + } + } +} \ No newline at end of file