Skip to content

Commit

Permalink
Merge pull request #3 from Tearth/v3.0-dev
Browse files Browse the repository at this point in the history
v3.0 (Luna), 12.12.2020
  • Loading branch information
Tearth authored Dec 12, 2020
2 parents 3c950eb + d6793de commit 1807217
Show file tree
Hide file tree
Showing 132 changed files with 4,115 additions and 582 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# Custom
/cloc.exe
/cloc.bat
/Cosette.Arbiter/settings.json
/Cosette.Arbiter/book.bin
/Cosette.Tuner/settings.json
/Cosette.Tuner/book.bin
/Cosette.Tuner.Web/Database.sqlite
/Cosette.Tuner.Web/wwwroot/lib/
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
# Version 3.0 (Luna), 12.12.2020
- Added better time control for Arbiter
- Added more UCI options
- Added Tuner project
- Added insufficient material detection
- Added executable hash generator
- Added abort when search lasts too long
- Added legality checking of the hash table moves
- Added SEE pruning in the quiescence search
- Added fianchetto evaluation
- Added internal iterative deepening
- Added a lot of UCI options, allowing for full engine customization
- Added multi-stage move ordering
- Added multi-stage move generating
- Fixed FEN parser when input didn't have halfmove clock and moves count
- Fixed crash when the engine was receiving invalid position in UCI mode
- Fixed UCI statistics
- Improved time scheduler when incrementation time is present
- Improved mobility calculation by rewarding for center control
- Improved late move reduction conditions
- Improved SEE accuracy (now includes x-ray attacks)
- Improved king safety evaluation
- Changed maximal moves count from 128 to 218 (according to Internet sources)
- Reduced size of transposition table entry (from 12 bytes to 8 bytes)
- Disabled most of the evaluation functions when the game is near to end
- Disabled returning of exact transposition table entries in the PV nodes
- Adjusted evaluation scores
- Optimized king safety evaluation
- Updated .NET Core runtime version to 5.0.100

Estimated strength: 2000 ELO

# Version 2.0 (Darkness), 19.10.2020
- Added fifty-move rule detection
- Added new evaluation functions: pawn shield, bishop pair, doubled rooks, a rook on open file
Expand Down
6 changes: 5 additions & 1 deletion Cosette.Arbiter/Cosette.Arbiter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand All @@ -17,6 +17,10 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Cosette.Polyglot\Cosette.Polyglot.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="book.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down
77 changes: 58 additions & 19 deletions Cosette.Arbiter/Engine/EngineOperator.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Cosette.Arbiter.Settings;

namespace Cosette.Arbiter.Engine
{
public class EngineOperator
{
private string _name;
public Lazy<string> ExecutableHash;

private string _enginePath;
private string _engineArguments;
private Process _engineProcess;

public EngineOperator(string name, string path)
public EngineOperator(string path, string arguments)
{
_name = name;
_enginePath = path;
_engineArguments = arguments;

ExecutableHash = new Lazy<string>(GetExecutableHash);
}

public void Init()
{
_engineProcess = Process.Start(new ProcessStartInfo
{
FileName = _enginePath,
Arguments = _engineArguments,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
Expand All @@ -30,20 +38,36 @@ public void Init()
Write("uci");
WaitForMessage("uciok");

SettingsLoader.Data.Options.ForEach(Write);
ApplyOptions();

Write("isready");
WaitForMessage("readyok");
}

public void Restart()
{
if (!_engineProcess.HasExited)
{
_engineProcess.Close();
}

Init();
ApplyOptions();
}

public void InitNewGame()
{
Write("ucinewgame");
Write("isready");
WaitForMessage("readyok");
}

public BestMoveData Go(List<string> moves)
public void ApplyOptions()
{
SettingsLoader.Data.Options.ForEach(Write);
}

public BestMoveData Go(List<string> moves, int whiteClock, int blackClock)
{
var bestMoveData = new BestMoveData();
var movesJoined = string.Join(' ', moves);
Expand All @@ -53,26 +77,22 @@ public BestMoveData Go(List<string> moves)
Write($"position startpos moves {movesJoined}");
}

Write($"go movetime {SettingsLoader.Data.MillisecondsPerMove}");
Write($"go wtime {whiteClock} btime {blackClock} winc {SettingsLoader.Data.IncTime} binc {SettingsLoader.Data.IncTime}");

while (true)
{
try
var response = Read();
if (response.StartsWith("info depth"))
{
var response = Read();
if (response.StartsWith("info depth"))
{
bestMoveData.LastInfoData = InfoData.FromString(response);
}
else if (response.StartsWith("bestmove"))
{
bestMoveData.BestMove = response.Split(' ')[1];
break;
}
bestMoveData.LastInfoData = InfoData.FromString(response);
}
catch
else if (response.StartsWith("bestmove"))
{
bestMoveData.BestMove = response.Split(' ')[1];
break;
}
else if (response.StartsWith("error"))
{
Init();
return null;
}
}
Expand All @@ -94,5 +114,24 @@ public void WaitForMessage(string message)
{
while (Read() != message) ;
}

private string GetExecutableHash()
{
var md5 = new MD5CryptoServiceProvider();
var path = _enginePath == "dotnet" ? _engineArguments : _enginePath;

using (var streamReader = new StreamReader(path))
{
md5.ComputeHash(streamReader.BaseStream);
}

var hashBuilder = new StringBuilder();
foreach (var b in md5.Hash)
{
hashBuilder.Append(b.ToString("x2"));
}

return hashBuilder.ToString();
}
}
}
1 change: 1 addition & 0 deletions Cosette.Arbiter/Settings/EngineData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class EngineData
{
public string Name { get; set; }
public string Path { get; set; }
public string Arguments { get; set; }
public int Rating { get; set; }
}
}
9 changes: 6 additions & 3 deletions Cosette.Arbiter/Settings/SettingsModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ public class SettingsModel
public List<EngineData> Engines { get; set; }
public List<string> Options { get; set; }

[JsonProperty("base_time")]
public int BaseTime { get; set; }

[JsonProperty("inc_time")]
public int IncTime { get; set; }

[JsonProperty("polyglot_opening_book")]
public string PolyglotOpeningBook { get; set; }

[JsonProperty("polyglot_max_moves")]
public int PolyglotMaxMoves { get; set; }

[JsonProperty("milliseconds_per_move")]
public int MillisecondsPerMove { get; set; }

[JsonProperty("max_moves_count")]
public int MaxMovesCount { get; set; }

Expand Down
4 changes: 3 additions & 1 deletion Cosette.Arbiter/Tournament/ArchivedGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ public class ArchivedGame
public GameData GameData { get; }
public TournamentParticipant Opponent { get; }
public GameResult Result { get; }
public bool TimeFlag { get; }

public ArchivedGame(GameData gameData, TournamentParticipant opponent, GameResult result)
public ArchivedGame(GameData gameData, TournamentParticipant opponent, GameResult result, bool timeFlag = false)
{
GameData = gameData;
Opponent = opponent;
Result = result;
TimeFlag = timeFlag;
}
}
}
28 changes: 26 additions & 2 deletions Cosette.Arbiter/Tournament/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,44 @@ public class GameData
public bool GameIsDone { get; private set; }
public Color Winner { get; private set; }

public int WhiteClock { get; private set; }
public int BlackClock { get; private set; }

private BestMoveData _lastBestMove;
private Color _colorToMove;

public GameData(List<string> opening)
{
HalfMovesDone = opening;
HalfMovesDone = new List<string>(opening);
WhiteClock = SettingsLoader.Data.BaseTime;
BlackClock = SettingsLoader.Data.BaseTime;

_colorToMove = Color.White;
}

public void MakeMove(BestMoveData bestMoveData)
{
HalfMovesDone.Add(bestMoveData.BestMove);
_lastBestMove = bestMoveData;


var clock = _colorToMove == Color.White ? WhiteClock : BlackClock;
clock -= bestMoveData.LastInfoData.Time;

if (clock <= 0)
{
GameIsDone = true;
WhiteClock = _colorToMove == Color.White ? clock : WhiteClock;
BlackClock = _colorToMove == Color.Black ? clock : BlackClock;

Winner = _colorToMove == Color.White ? Color.Black : Color.White;
return;
}

clock += SettingsLoader.Data.IncTime;

WhiteClock = _colorToMove == Color.White ? clock : WhiteClock;
BlackClock = _colorToMove == Color.Black ? clock : BlackClock;

if (IsCheckmate() || bestMoveData.LastInfoData.ScoreCp >= 2000)
{
GameIsDone = true;
Expand Down
Loading

0 comments on commit 1807217

Please sign in to comment.