Skip to content

Commit

Permalink
Added 400m FRC datapoints
Browse files Browse the repository at this point in the history
-> +132 ELO STC FRC
Released v 1.2.2
  • Loading branch information
Timmoth committed Oct 13, 2024
1 parent 97c0687 commit ce8f0f9
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
working-directory: src/Sapling
id: get_version
run: |
VERSION=1.2.1
VERSION=1.2.2
echo "Application version: $VERSION"
echo "::set-output name=version::$VERSION"
Expand Down
135 changes: 135 additions & 0 deletions src/Sapling.Engine/DataGen/Chess960.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
namespace Sapling.Engine.DataGen;

using System.Collections.Generic;
using System.Linq;

public static class Chess960
{
public static string[] Fens;

static Chess960()
{
char[] board = new char[8];
var fens = new HashSet<string>();
GenerateBishops(board, fens);
Fens = fens.ToArray();
}

// Step 1: Place bishops on opposite-colored squares
private static void GenerateBishops(char[] board, HashSet<string> fenList)
{
for (int b1 = 0; b1 < 8; b1 += 2) // Dark square bishop
{
for (int b2 = 1; b2 < 8; b2 += 2) // Light square bishop
{
board[b1] = 'B';
board[b2] = 'B';
GenerateRooksAndKing(board, fenList); // Proceed to place rooks and king
board[b1] = '\0';
board[b2] = '\0';
}
}
}

// Step 2: Place the king between the two rooks
private static void GenerateRooksAndKing(char[] board, HashSet<string> fenList)
{
for (int r1 = 0; r1 < 8; r1++)
{
if (board[r1] != '\0') continue; // Skip occupied squares (bishops)

for (int r2 = r1 + 1; r2 < 8; r2++)
{
if (board[r2] != '\0') continue;

// Ensure the king is placed between the two rooks
for (int k = r1 + 1; k < r2; k++)
{
if (board[k] == '\0') // The square must be free for the king
{
board[r1] = 'R';
board[r2] = 'R';
board[k] = 'K';
GenerateKnightsAndQueen(board, fenList); // Proceed to place knights and queen
board[r1] = '\0';
board[r2] = '\0';
board[k] = '\0';
}
}
}
}
}

// Step 3: Place knights and queen in remaining empty squares
private static void GenerateKnightsAndQueen(char[] board, HashSet<string> fenList)
{
List<int> emptySquares = new List<int>();
for (int i = 0; i < 8; i++)
{
if (board[i] == '\0')
{
emptySquares.Add(i);
}
}

// There are 3 empty squares remaining, so permute 'N', 'N', 'Q'
char[] remainingPieces = { 'N', 'N', 'Q' };
Permute(remainingPieces, 0, board, emptySquares, fenList);
}

// Step 4: Permute remaining knights and queen, placing them on the board
private static void Permute(char[] pieces, int index, char[] board, List<int> emptySquares, HashSet<string> fenList)
{
if (index == pieces.Length)
{
// Fill the empty squares with the current permutation
for (int i = 0; i < emptySquares.Count; i++)
{
board[emptySquares[i]] = pieces[i];
}

// Generate the FEN string with Shredder-style castling rights
var castlingRights = GetShredderCastlingRights(board);
var fen = string.Join("", board).ToLower() + "/pppppppp/8/8/8/8/PPPPPPPP/" + string.Join("", board).ToUpper() + " w " + castlingRights.ToUpper()+ castlingRights.ToLower() + " - 0 1";
fenList.Add(fen);

// Clear the board for the next permutation
foreach (var indexToClear in emptySquares)
{
board[indexToClear] = '\0';
}

return;
}

for (int i = index; i < pieces.Length; i++)
{
Swap(ref pieces[index], ref pieces[i]);
Permute(pieces, index + 1, board, emptySquares, fenList);
Swap(ref pieces[index], ref pieces[i]); // Backtrack
}
}

// Helper function to swap pieces in the permutation
private static void Swap(ref char a, ref char b)
{
(a, b) = (b, a);
}

// Generate castling rights in Shredder FEN format by checking rook positions
private static string GetShredderCastlingRights(char[] board)
{
string castlingRights = "";

// Find the positions of the rooks (R) and convert them to file letters (a-h)
for (int i = 0; i < 8; i++)
{
if (board[i] == 'R')
{
castlingRights += (char)('a' + i); // Convert index to file letter
}
}

return castlingRights;
}
}
17 changes: 14 additions & 3 deletions src/Sapling.Engine/DataGen/DataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace Sapling.Engine.DataGen;

using System;

public class DataGeneratorStats
{
public BoardStateData InitialBoard = default;
Expand Down Expand Up @@ -73,6 +75,9 @@ public void Output()
}
public class DataGenerator
{
public const bool Is960 = true;
public const int RandomMoves = 8;

public const int MaxTurnCount = 500;

public bool Cancelled = false;
Expand Down Expand Up @@ -140,8 +145,14 @@ private unsafe void RunWorker(DataGeneratorStats stats)
}

stats.Output(dataGenPositions, positions, result);

gameState.ResetTo(ref stats.InitialBoard, initialLegalMoves);
if (Is960)
{
gameState.ResetToFen(Chess960.Fens[Random.Shared.Next(0, 960)]);
}
else
{
gameState.ResetTo(ref stats.InitialBoard, initialLegalMoves);

Check warning on line 154 in src/Sapling.Engine/DataGen/DataGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Unreachable code detected

Check warning on line 154 in src/Sapling.Engine/DataGen/DataGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Unreachable code detected

Check warning on line 154 in src/Sapling.Engine/DataGen/DataGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Unreachable code detected

Check warning on line 154 in src/Sapling.Engine/DataGen/DataGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Unreachable code detected

Check warning on line 154 in src/Sapling.Engine/DataGen/DataGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Unreachable code detected
}
}
catch (Exception ex)
{
Expand All @@ -161,7 +172,7 @@ private unsafe void RunWorker(DataGeneratorStats stats)
while (!gameState.GameOver() && gameState.Board.TurnCount < MaxTurnCount && !IsAdjudicatedDraw(gameState, drawScoreCount))
{
uint move;
if (randomMoveCount <= 8)
if (randomMoveCount <= RandomMoves)
{
move = gameState.LegalMoves[Random.Shared.Next(0, gameState.LegalMoves.Count)];
randomMoveCount++;
Expand Down
16 changes: 8 additions & 8 deletions src/Sapling.Engine/MoveGen/MoveGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -653,13 +653,13 @@ public static unsafe void GenerateWhiteKingPseudoLegalMoves(this ref BoardStateD
var startSquare = Math.Min(board.WhiteKingSquare, Math.Min(rookSquare, 5));
var endSquare = Math.Max(board.WhiteKingSquare, Math.Max(rookSquare, 6));

ulong path = (*(AttackTables.LineBitBoardsInclusive + startSquare * 64 + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.WhiteKingSquare));
ulong path = (*(AttackTables.LineBitBoardsInclusive + (startSquare << 6) + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.WhiteKingSquare));
if (path == 0)
{
var canCastle = true;
var kingStart = Math.Min((int)board.WhiteKingSquare, 6);
var kingEnd = Math.Max((int)board.WhiteKingSquare, 6);
for (var i = kingStart; i <= kingEnd; i++)
for (var i = kingEnd; i >= kingStart; i--)
{
if (board.IsAttackedByBlack(i))
{
Expand All @@ -682,14 +682,14 @@ public static unsafe void GenerateWhiteKingPseudoLegalMoves(this ref BoardStateD
var rookSquare = board.Is960 ? board.WhiteQueenSideTargetSquare : 0;
var startSquare = Math.Min(board.WhiteKingSquare, Math.Min(rookSquare, 2));
var endSquare = Math.Max(board.WhiteKingSquare, Math.Max(rookSquare, 3));
ulong path = (*(AttackTables.LineBitBoardsInclusive + startSquare * 64 + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.WhiteKingSquare));
ulong path = (*(AttackTables.LineBitBoardsInclusive + (startSquare << 6) + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.WhiteKingSquare));

if (path == 0)
{
bool canCastle = true;
var kingStart = Math.Min((int)board.WhiteKingSquare, 2);
var kingEnd = Math.Max((int)board.WhiteKingSquare, 2);
for (var i = kingStart; i <= kingEnd; i++)
for (var i = kingEnd; i >= kingStart; i--)
{
if (board.IsAttackedByBlack(i))
{
Expand Down Expand Up @@ -747,15 +747,15 @@ public static unsafe void GetBlackKingPseudoLegalMoves(this ref BoardStateData b
var startSquare = Math.Min(board.BlackKingSquare, Math.Min(rookSquare, 61));
var endSquare = Math.Max(board.BlackKingSquare, Math.Max(rookSquare, 62));

ulong path = (*(AttackTables.LineBitBoardsInclusive + startSquare * 64 + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.BlackKingSquare));
ulong path = (*(AttackTables.LineBitBoardsInclusive + (startSquare << 6) + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.BlackKingSquare));

if (path == 0)
{
bool canCastle = true;
var kingStart = Math.Min((int)board.BlackKingSquare, 62);
var kingEnd = Math.Max((int)board.BlackKingSquare, 62);

for (var i = kingStart; i <= kingEnd; i++)
for (var i = kingEnd; i >= kingStart; i--)
{
if (board.IsAttackedByWhite(i))
{
Expand All @@ -779,14 +779,14 @@ public static unsafe void GetBlackKingPseudoLegalMoves(this ref BoardStateData b
var startSquare = Math.Min(board.BlackKingSquare, Math.Min(rookSquare, 58));
var endSquare = Math.Max(board.BlackKingSquare, Math.Max(rookSquare, 59));

ulong path = (*(AttackTables.LineBitBoardsInclusive + startSquare * 64 + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.BlackKingSquare));
ulong path = (*(AttackTables.LineBitBoardsInclusive + (startSquare << 6) + endSquare) & board.Occupancy[Constants.Occupancy]) & ~((1UL << rookSquare) | (1UL << board.BlackKingSquare));

if (path == 0)
{
bool canCastle = true;
var kingStart = Math.Min((int)board.BlackKingSquare, 58);
var kingEnd = Math.Max((int)board.BlackKingSquare, 58);
for (var i = kingStart; i <= kingEnd; i++)
for (var i = kingEnd; i >= kingStart; i--)
{
if (board.IsAttackedByWhite(i))
{
Expand Down
Binary file not shown.
8 changes: 8 additions & 0 deletions src/Sapling.Engine/Resources/WeightsHistory/log.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,11 @@ Data: 1.7bn positions
WDL: 0.3
LR: CosineDecayLR 0.001 * 0.3 * 0.3 * 0.3
SuperBatches: 260

----------------------------------
20_(768x4-1024)x2-8
----------------------------------
Data: 2bn positions (400m FRC)
WDL: 0.3
LR: CosineDecayLR 0.001 * 0.3 * 0.3 * 0.3
SuperBatches: 300
Binary file modified src/Sapling.Engine/Resources/sapling.nnue
Binary file not shown.
42 changes: 21 additions & 21 deletions src/Sapling.Engine/Tuning/SpsaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ public static unsafe class SpsaOptions
[SpsaMinValue("1400"), SpsaMaxValue("3000")]
public static int AsperationWindowE = 2662;
#else
public const int ReverseFutilityPruningMargin = 68;
public const int ReverseFutilityPruningMargin = 67;
public const int ReverseFutilityPruningDepth = 7;
public const int NullMovePruningDepth = 2;
public const float NullMovePruningReductionA = 3;
public const float NullMovePruningReductionB = 4;
public const float NullMovePruningReductionC = 3;
public const int RazorMarginA = 57;
public const int RazorMarginB = 370;
public const int RazorMarginA = 58;
public const int RazorMarginB = 378;
public const int InternalIterativeDeepeningDepth = 2;
public const int LateMovePruningConstant = 8;
public const int LateMoveReductionMinDepth = 3;
Expand All @@ -168,26 +168,26 @@ public static unsafe class SpsaOptions
public const float LateMoveReductionInterestingB = 2.4956496f;
public const float LateMoveReductionA = 1.315961f;
public const float LateMoveReductionB = 2.7831153f;
public const int HistoryHeuristicMaxHistory = 9599;
public const int HistoryHeuristicBonusMax = 425;
public const int HistoryHeuristicBonusCoeff = 86;
public const int MoveOrderingBestMoveBias = 240615;
public const int MoveOrderingEnPassantMoveBias = 77989;
public const int MoveOrderingWinningCaptureBias = 142295;
public const int MoveOrderingLosingCaptureBias = 15778;
public const int MoveOrderingPromoteBias = 45184;
public const int MoveOrderingCapturePromoteBias = 30512;
public const int MoveOrderingKillerABias = 61238;
public const int MoveOrderingCounterMoveBias = 87526;
public const int InterestingNegaMaxMoveScore = 40731;
public const int InterestingQuiescenceMoveScore = 40988;
public const int HistoryHeuristicMaxHistory = 9532;
public const int HistoryHeuristicBonusMax = 406;
public const int HistoryHeuristicBonusCoeff = 83;
public const int MoveOrderingBestMoveBias = 239130;
public const int MoveOrderingEnPassantMoveBias = 78671;
public const int MoveOrderingWinningCaptureBias = 134191;
public const int MoveOrderingLosingCaptureBias = 16845;
public const int MoveOrderingPromoteBias = 46577;
public const int MoveOrderingCapturePromoteBias = 35558;
public const int MoveOrderingKillerABias = 66845;
public const int MoveOrderingCounterMoveBias = 87003;
public const int InterestingNegaMaxMoveScore = 40775;
public const int InterestingQuiescenceMoveScore = 35432;
public const int ProbCutBetaMargin = 220;
public const int ProbCutMinDepth = 3;
public const int AsperationWindowA = 38;
public const int AsperationWindowB = 60;
public const int AsperationWindowC = 275;
public const int AsperationWindowD = 837;
public const int AsperationWindowE = 2662;
public const int AsperationWindowA = 37;
public const int AsperationWindowB = 59;
public const int AsperationWindowC = 279;
public const int AsperationWindowD = 847;
public const int AsperationWindowE = 2785;
#endif

public static int* LateMovePruningInterestingReductionTable;
Expand Down
2 changes: 1 addition & 1 deletion src/Sapling/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal class Program
private static StreamWriter _logWriter;

private static void Main(string[] args)
{
{
Console.SetIn(new StreamReader(Console.OpenStandardInput(), Encoding.UTF8, false, 2048 * 4));

if (args.Length > 0 && args[0] == "--version")
Expand Down
6 changes: 3 additions & 3 deletions src/Sapling/Sapling.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<Nullable>enable</Nullable>
<ApplicationIcon>logo.ico</ApplicationIcon>
<Title>Sapling</Title>
<AssemblyVersion>1.2.1.0</AssemblyVersion>
<FileVersion>1.2.1.0</FileVersion>
<Version>1.2.1.0</Version>
<AssemblyVersion>1.2.2.0</AssemblyVersion>
<FileVersion>1.2.2.0</FileVersion>
<Version>1.2.2.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

Expand Down

0 comments on commit ce8f0f9

Please sign in to comment.