Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,5 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml
**/out/
**/.idea/
15 changes: 15 additions & 0 deletions Chess-Challenge.Uci/Chess-Challenge.Uci.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>ChessChallenge.Bot</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Chess-Challenge\Chess-Challenge.csproj" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions Chess-Challenge.Uci/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// See https://aka.ms/new-console-template for more information

using ChessChallenge.Bot;

var engine = new UciEngine();
var message = string.Empty;
var run = true;
while (run)
{
message = Console.ReadLine();
run = string.IsNullOrEmpty(message) || engine.ReceiveCommand(message);
}
117 changes: 117 additions & 0 deletions Chess-Challenge.Uci/UciEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using ChessChallenge.API;
using ChessChallenge.Chess;
using Board = ChessChallenge.Chess.Board;
using Move = ChessChallenge.Chess.Move;
using Timer = ChessChallenge.API.Timer;

namespace ChessChallenge.Bot;

public class UciEngine
{
private const string UciInit = "uci";
private const string UciOkay = "uciok";
private const string IsReady = "isready";
private const string ReadyOk = "readyok";
private const string NewGame = "ucinewgame";
private const string Position = "position";
private const string BestMove = "bestmove";
private const string Go = "go";
private const string Stop = "stop";
private const string Quit = "quit";

private const string BotMatchStartFens = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";

private readonly MyBot _bot = new MyBot();
private Board _currentBoard;

private const string LogFile = "./comm-log.txt";
private const string UciLog = "./uci-log.txt";
private const string ErrorFile = "./error.log";
private const string DateFormat = "yyyyMMddTHHmmss";

private void WriteLineToDisk(string line, string file)
{
using StreamWriter outputFile = new StreamWriter(file, true);

outputFile.WriteLine(line);

}
public bool ReceiveCommand(string message)
{
var messageType = message.Split(' ')[0];
WriteLineToDisk($"{DateTimeOffset.Now.ToString(DateFormat)} -- Received message {message}", LogFile);
WriteLineToDisk($"{DateTimeOffset.Now.ToString(DateFormat)}{message}", UciLog);
try
{
switch (messageType)
{
case UciInit:
Respond(UciOkay);
return true;
case IsReady:
Respond(ReadyOk);
return true;
case NewGame:
_currentBoard = new Board();
_currentBoard.LoadPosition(BotMatchStartFens);
return true;
case Position:
ProcessPositionCommand(message);
return true;
case Go:
ProcessGoCommand(message);
return true;
case Stop:
return true;
case Quit:
default:
return false;
}
}
catch (Exception ex)
{
if (ex.StackTrace != null)
{
var errorMessage = $"{DateTimeOffset.Now.ToString(DateFormat)} -- {ex.Message}\n{ex.StackTrace}";
WriteLineToDisk(errorMessage, ErrorFile);

}
}

return false;

}

private void ProcessStopCommand()
{
throw new NotImplementedException();
}

private void ProcessGoCommand(string message)
{
var split = message.Split(' ');
var millis = int.Parse(split[2]);
var newMove = new Move(_bot.Think(new(_currentBoard), new (millis)).RawValue);
var moveNameUci = MoveUtility.GetMoveNameUCI(newMove);
Respond($"{BestMove} {moveNameUci}");
}

private void ProcessPositionCommand(string message)
{
_currentBoard = new Board();
_currentBoard.LoadPosition(BotMatchStartFens);
var moveStrings = message.Split(' ');
if (moveStrings[^1] == "startpos") return;
for (var i = 3; i < moveStrings.Length; i++)
{
var newMove = MoveUtility.GetMoveFromUCIName(moveStrings[i], _currentBoard);
_currentBoard.MakeMove(newMove, false);
}
}

private void Respond(string response)
{
WriteLineToDisk($"Responding: {response}", LogFile);
Console.WriteLine(response);
}
}
7 changes: 7 additions & 0 deletions Chess-Challenge.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chess-Challenge.Uci", "Chess-Challenge.Uci\Chess-Challenge.Uci.csproj", "{75253019-D4F1-4560-859C-F7C2AC61052A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -20,6 +23,10 @@ Global
{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
{75253019-D4F1-4560-859C-F7C2AC61052A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75253019-D4F1-4560-859C-F7C2AC61052A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75253019-D4F1-4560-859C-F7C2AC61052A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75253019-D4F1-4560-859C-F7C2AC61052A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down