-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Tearth/v2.0-dev
v2.0 (Darkness), 19.10.2020
- Loading branch information
Showing
135 changed files
with
3,504 additions
and
1,331 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -349,3 +349,4 @@ MigrationBackup/ | |
.ionide/ | ||
/cloc.exe | ||
/cloc.bat | ||
/Cosette.Arbiter/settings.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,28 @@ | ||
# Version 1.0 (Aqua), 19-09-2020 | ||
* Initial version | ||
# 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 | ||
- Added "evaluate" command to get FEN position evaluation | ||
- Added ability to postpone moves generation before PV move check | ||
- Added evaluation hash table | ||
- Added Arbiter app to speed up the process of testing engine | ||
- Added support for UCI's winc and binc | ||
- Fixed PV node detection | ||
- Fixed invalid detection of passing pawns | ||
- Fixed invalid best move when a search has been aborted | ||
- Fixed static exchange evaluation - in rare cases the table was returning an invalid score | ||
- Improved method of probing piece type at the specified field | ||
- Improved time management - now allocated time depends on the moves count | ||
- Improved move ordering: castling and better promotions are now prioritized | ||
- Improved transposition tables: entries are now smaller, have proper checkmate scores (relative to position) and are used between moves (aging) | ||
- Redefined and reduced the size of Move structure (from 4 bytes to 2 bytes) | ||
- Reduced size of transposition table entry (from 16 bytes to 12 bytes), evaluation hash table entry (from 8 bytes to 4 bytes) and pawn hash table entry (from 8 bytes to 4 bytes) | ||
- Optimized printing UCI output | ||
- Adjusted move ordering scores | ||
- Updated .NET Core runtime version to 3.1.403 | ||
|
||
Estimated strength: 1950 ELO | ||
|
||
# Version 1.0 (Aqua), 19.09.2020 | ||
- Initial version | ||
|
||
Estimated strength: 1900 ELO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.0" /> | ||
<PackageReference Include="xunit" Version="2.4.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||
<PackageReference Include="coverlet.collector" Version="1.2.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Cosette.Arbiter\Cosette.Arbiter.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Cosette.Arbiter.Book; | ||
using Xunit; | ||
|
||
namespace Cosette.Arbiter.Tests | ||
{ | ||
public class HashKeyTests | ||
{ | ||
[Theory] | ||
[InlineData(new string[] { }, 5060803636482931868)] | ||
[InlineData(new[] { "e2e4" }, 9384546495678726550)] | ||
[InlineData(new[] { "e2e4", "d7d5" }, 528813709611831216)] | ||
[InlineData(new[] { "e2e4", "d7d5", "e4e5", }, 7363297126586722772)] | ||
[InlineData(new[] { "e2e4", "d7d5", "e4e5", "f7f5" }, 2496273314520498040)] | ||
[InlineData(new[] { "e2e4", "d7d5", "e4e5", "f7f5", "e1e2" }, 7289745035295343297)] | ||
[InlineData(new[] { "e2e4", "d7d5", "e4e5", "f7f5", "e1e2", "e8f7" }, 71445182323015129)] | ||
[InlineData(new[] { "a2a4", "b7b5", "h2h4", "b5b4", "c2c4" }, 4359805404264691255)] | ||
[InlineData(new[] { "a2a4", "b7b5", "h2h4", "b5b4", "c2c4", "b4c3", "a1a3" }, 6647202560273257824)] | ||
public void HashKey_FromInitialPosition(string[] moves, ulong expectedHashKey) | ||
{ | ||
var polyglotBoard = new PolyglotBoard(); | ||
polyglotBoard.InitDefaultState(); | ||
|
||
foreach (var move in moves) | ||
{ | ||
polyglotBoard.MakeMove(move); | ||
} | ||
|
||
Assert.Equal(expectedHashKey, polyglotBoard.CalculateHash()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
|
||
namespace Cosette.Arbiter.Book | ||
{ | ||
[Flags] | ||
public enum CastlingFlags | ||
{ | ||
None = 0, | ||
WhiteShort = 1, | ||
WhiteLong = 2, | ||
BlackShort = 4, | ||
BlackLong = 8, | ||
WhiteCastling = WhiteShort | WhiteLong, | ||
BlackCastling = BlackShort | BlackLong, | ||
Everything = WhiteShort | WhiteLong | BlackShort | BlackLong | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace Cosette.Arbiter.Book | ||
{ | ||
public enum ColorType | ||
{ | ||
White, | ||
Black | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace Cosette.Arbiter.Book | ||
{ | ||
public enum PieceType | ||
{ | ||
None = -1, | ||
BlackPawn, | ||
WhitePawn, | ||
BlackKnight, | ||
WhiteKnight, | ||
BlackBishop, | ||
WhiteBishop, | ||
BlackRook, | ||
WhiteRook, | ||
BlackQueen, | ||
WhiteQueen, | ||
BlackKing, | ||
WhiteKing | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
using System; | ||
|
||
namespace Cosette.Arbiter.Book | ||
{ | ||
public class PolyglotBoard | ||
{ | ||
private PieceType[,] _state; | ||
private CastlingFlags _castlingFlags; | ||
private ColorType _colorToMove; | ||
private int _enPassantFile; | ||
|
||
public PolyglotBoard() | ||
{ | ||
_state = new PieceType[8,8]; | ||
_castlingFlags = CastlingFlags.Everything; | ||
_colorToMove = ColorType.White; | ||
_enPassantFile = -1; | ||
} | ||
|
||
public void InitDefaultState() | ||
{ | ||
for (var file = 0; file < 8; file++) | ||
{ | ||
for (var rank = 0; rank < 8; rank++) | ||
{ | ||
_state[file, rank] = PieceType.None; | ||
} | ||
} | ||
|
||
_state[0, 0] = PieceType.WhiteRook; | ||
_state[1, 0] = PieceType.WhiteKnight; | ||
_state[2, 0] = PieceType.WhiteBishop; | ||
_state[3, 0] = PieceType.WhiteQueen; | ||
_state[4, 0] = PieceType.WhiteKing; | ||
_state[5, 0] = PieceType.WhiteBishop; | ||
_state[6, 0] = PieceType.WhiteKnight; | ||
_state[7, 0] = PieceType.WhiteRook; | ||
|
||
_state[0, 1] = PieceType.WhitePawn; | ||
_state[1, 1] = PieceType.WhitePawn; | ||
_state[2, 1] = PieceType.WhitePawn; | ||
_state[3, 1] = PieceType.WhitePawn; | ||
_state[4, 1] = PieceType.WhitePawn; | ||
_state[5, 1] = PieceType.WhitePawn; | ||
_state[6, 1] = PieceType.WhitePawn; | ||
_state[7, 1] = PieceType.WhitePawn; | ||
|
||
_state[0, 6] = PieceType.BlackPawn; | ||
_state[1, 6] = PieceType.BlackPawn; | ||
_state[2, 6] = PieceType.BlackPawn; | ||
_state[3, 6] = PieceType.BlackPawn; | ||
_state[4, 6] = PieceType.BlackPawn; | ||
_state[5, 6] = PieceType.BlackPawn; | ||
_state[6, 6] = PieceType.BlackPawn; | ||
_state[7, 6] = PieceType.BlackPawn; | ||
|
||
_state[0, 7] = PieceType.BlackRook; | ||
_state[1, 7] = PieceType.BlackKnight; | ||
_state[2, 7] = PieceType.BlackBishop; | ||
_state[3, 7] = PieceType.BlackQueen; | ||
_state[4, 7] = PieceType.BlackKing; | ||
_state[5, 7] = PieceType.BlackBishop; | ||
_state[6, 7] = PieceType.BlackKnight; | ||
_state[7, 7] = PieceType.BlackRook; | ||
} | ||
|
||
public void MakeMove(string move) | ||
{ | ||
var (fromFile, fromRank) = (move[0] - 'a', move[1] - '1'); | ||
var (toFile, toRank) = (move[2] - 'a', move[3] - '1'); | ||
var pieceType = _state[fromFile, fromRank]; | ||
var oldEnPassant = _enPassantFile; | ||
|
||
// Pieces | ||
_state[toFile, toRank] = _state[fromFile, fromRank]; | ||
_state[fromFile, fromRank] = PieceType.None; | ||
_enPassantFile = -1; | ||
|
||
// Castling | ||
if (pieceType == PieceType.WhiteKing) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.WhiteCastling; | ||
|
||
if (Math.Abs(fromFile - toFile) == 2) | ||
{ | ||
// Short castling | ||
if (fromFile < toFile) | ||
{ | ||
_state[7, 0] = PieceType.None; | ||
_state[5, 0] = PieceType.WhiteRook; | ||
} | ||
// Long castling | ||
else | ||
{ | ||
_state[0, 0] = PieceType.None; | ||
_state[3, 0] = PieceType.WhiteRook; | ||
} | ||
} | ||
} | ||
else if (pieceType == PieceType.BlackKing) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.BlackCastling; | ||
|
||
if (Math.Abs(fromFile - toFile) == 2) | ||
{ | ||
// Short castling | ||
if (fromFile < toFile) | ||
{ | ||
_state[7, 7] = PieceType.None; | ||
_state[5, 7] = PieceType.BlackRook; | ||
} | ||
// Long castling | ||
else | ||
{ | ||
_state[0, 7] = PieceType.None; | ||
_state[3, 7] = PieceType.BlackRook; | ||
} | ||
} | ||
} | ||
else if (pieceType == PieceType.WhiteRook && fromFile == 0 && fromRank == 0) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.WhiteLong; | ||
} | ||
else if (pieceType == PieceType.WhiteRook && fromFile == 7 && fromRank == 0) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.WhiteShort; | ||
} | ||
else if (pieceType == PieceType.BlackRook && fromFile == 0 && fromRank == 7) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.BlackLong; | ||
} | ||
else if (pieceType == PieceType.BlackRook && fromFile == 7 && fromRank == 7) | ||
{ | ||
_castlingFlags &= ~CastlingFlags.BlackShort; | ||
} | ||
|
||
// En passant | ||
if (pieceType == PieceType.WhitePawn || pieceType == PieceType.BlackPawn) | ||
{ | ||
if (Math.Abs(fromRank - toRank) == 2) | ||
{ | ||
var targetPieceType = _colorToMove == ColorType.White ? PieceType.BlackPawn : PieceType.WhitePawn; | ||
if (toFile > 0 && _state[toFile - 1, toRank] == targetPieceType || | ||
toFile < 7 && _state[toFile + 1, toRank] == targetPieceType) | ||
{ | ||
_enPassantFile = toFile; | ||
} | ||
} | ||
else if (Math.Abs(fromFile - toFile) == 1 && toFile == oldEnPassant) | ||
{ | ||
if (_colorToMove == ColorType.White) | ||
{ | ||
_state[toFile, toRank - 1] = PieceType.None; | ||
} | ||
else if (_colorToMove == ColorType.Black) | ||
{ | ||
_state[toFile, toRank + 1] = PieceType.None; | ||
} | ||
} | ||
} | ||
|
||
// Color | ||
_colorToMove = _colorToMove == ColorType.White ? ColorType.Black : ColorType.White; | ||
} | ||
|
||
public ulong CalculateHash() | ||
{ | ||
ulong result = 0; | ||
|
||
for (var file = 0; file < 8; file++) | ||
{ | ||
for (var rank = 0; rank < 8; rank++) | ||
{ | ||
if (_state[file, rank] != PieceType.None) | ||
{ | ||
result ^= PolyglotConstants.Keys[64 * (int)_state[file, rank] + 8 * rank + file]; | ||
} | ||
} | ||
} | ||
|
||
if ((_castlingFlags & CastlingFlags.WhiteShort) != 0) | ||
{ | ||
result ^= PolyglotConstants.Keys[768]; | ||
} | ||
if ((_castlingFlags & CastlingFlags.WhiteLong) != 0) | ||
{ | ||
result ^= PolyglotConstants.Keys[769]; | ||
} | ||
if ((_castlingFlags & CastlingFlags.BlackShort) != 0) | ||
{ | ||
result ^= PolyglotConstants.Keys[770]; | ||
} | ||
if ((_castlingFlags & CastlingFlags.BlackLong) != 0) | ||
{ | ||
result ^= PolyglotConstants.Keys[771]; | ||
} | ||
|
||
if (_enPassantFile != -1) | ||
{ | ||
result ^= PolyglotConstants.Keys[772 + _enPassantFile]; | ||
} | ||
|
||
if (_colorToMove == ColorType.White) | ||
{ | ||
result ^= PolyglotConstants.Keys[780]; | ||
} | ||
|
||
return result; | ||
} | ||
} | ||
} |
Oops, something went wrong.