Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡ Remove Move.CapturedPiece #1020

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
35 changes: 19 additions & 16 deletions src/Lynx.Benchmark/MakeUnmakeMove_implementation_Benchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ public struct MakeMovePosition

public BitBoard[] OccupancyBitBoards { get; }

public int[] Board { get; }

public Side Side { get; private set; }

public BoardSquare EnPassant { get; private set; }
Expand All @@ -307,11 +309,12 @@ public MakeMovePosition(string fen) : this(FENParser.ParseFEN(fen))
{
}

public MakeMovePosition((BitBoard[] PieceBitBoards, BitBoard[] OccupancyBitBoards, Side Side, byte Castle, BoardSquare EnPassant,
public MakeMovePosition((BitBoard[] PieceBitBoards, BitBoard[] OccupancyBitBoards, int[] board, Side Side, byte Castle, BoardSquare EnPassant,
int HalfMoveClock/*, int FullMoveCounter*/) parsedFEN)
{
PieceBitBoards = parsedFEN.PieceBitBoards;
OccupancyBitBoards = parsedFEN.OccupancyBitBoards;
Board = parsedFEN.board;
Side = parsedFEN.Side;
Castle = parsedFEN.Castle;
EnPassant = parsedFEN.EnPassant;
Expand All @@ -333,6 +336,9 @@ public MakeMovePosition(MakeMovePosition position)
OccupancyBitBoards = new BitBoard[3];
Array.Copy(position.OccupancyBitBoards, OccupancyBitBoards, position.OccupancyBitBoards.Length);

Board = new int[64];
Array.Copy(position.Board, Board, position.Board.Length);

Side = position.Side;
Castle = position.Castle;
EnPassant = position.EnPassant;
Expand All @@ -354,6 +360,9 @@ public MakeMovePosition(MakeMovePosition position, bool nullMove)
OccupancyBitBoards = new BitBoard[3];
Array.Copy(position.OccupancyBitBoards, OccupancyBitBoards, position.OccupancyBitBoards.Length);

Board = new int[64];
Array.Copy(position.Board, Board, position.Board.Length);

Side = (Side)Utils.OppositeSide(position.Side);
Castle = position.Castle;
EnPassant = BoardSquare.noSquare;
Expand Down Expand Up @@ -824,7 +833,6 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey(Move move)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_PreSwitchSpecialMove(Move move)
{
int capturedPiece = -1;
byte castleCopy = Castle;
BoardSquare enpassantCopy = EnPassant;
long uniqueIdentifierCopy = UniqueIdentifier;
Expand All @@ -837,6 +845,7 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_PreSwitchSpecialM
int targetSquare = move.TargetSquare();
int piece = move.Piece();
int promotedPiece = move.PromotedPiece();
int capturedPiece = Board[targetSquare];

var newPiece = piece;
if (promotedPiece != default)
Expand Down Expand Up @@ -869,10 +878,6 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_PreSwitchSpecialM
capturedSquare = Constants.EnPassantCaptureSquares[targetSquare];
Utils.Assert(PieceBitBoards[oppositePawnIndex].GetBit(capturedSquare), $"Expected {(Side)oppositeSide} pawn in {capturedSquare}");
}
else
{
capturedPiece = move.CapturedPiece();
}

PieceBitBoards[capturedPiece].PopBit(capturedSquare);
OccupancyBitBoards[oppositeSide].PopBit(capturedSquare);
Expand Down Expand Up @@ -935,8 +940,6 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_PreSwitchSpecialM
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_SwitchSpecialMove(Move move)
{
int capturedPiece = -1;

byte castleCopy = Castle;
BoardSquare enpassantCopy = EnPassant;
long uniqueIdentifierCopy = UniqueIdentifier;
Expand All @@ -949,6 +952,7 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_SwitchSpecialMove
int targetSquare = move.TargetSquare();
int piece = move.Piece();
int promotedPiece = move.PromotedPiece();
int capturedPiece = Board[targetSquare];

var newPiece = piece;
if (promotedPiece != default)
Expand Down Expand Up @@ -978,7 +982,6 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_SwitchSpecialMove
if (move.IsCapture())
{
var capturedSquare = targetSquare;
capturedPiece = move.CapturedPiece();

PieceBitBoards[capturedPiece].PopBit(capturedSquare);
OccupancyBitBoards[oppositeSide].PopBit(capturedSquare);
Expand Down Expand Up @@ -1036,11 +1039,9 @@ public MakeMoveGameStateWithZobristKey MakeMove_WithZobristKey_SwitchSpecialMove
}
case SpecialMoveType.EnPassant:
{
var oppositePawnIndex = (int)Piece.p - offset;

var capturedSquare = Constants.EnPassantCaptureSquares[targetSquare];
capturedPiece = oppositePawnIndex;
Utils.Assert(PieceBitBoards[oppositePawnIndex].GetBit(capturedSquare), $"Expected {(Side)oppositeSide} pawn in {capturedSquare}");
capturedPiece = (int)Piece.p - offset;
Utils.Assert(PieceBitBoards[capturedPiece].GetBit(capturedSquare), $"Expected {(Side)oppositeSide} pawn in {capturedSquare}");

PieceBitBoards[capturedPiece].PopBit(capturedSquare);
OccupancyBitBoards[oppositeSide].PopBit(capturedSquare);
Expand Down Expand Up @@ -1151,6 +1152,7 @@ public void UnmakeMove_WithZobristKey_PreSwitchSpecialMove(Move move, MakeMoveGa
int targetSquare = move.TargetSquare();
int piece = move.Piece();
int promotedPiece = move.PromotedPiece();
int capturedPiece = Board[targetSquare];

var newPiece = piece;
if (promotedPiece != default)
Expand Down Expand Up @@ -1179,7 +1181,7 @@ public void UnmakeMove_WithZobristKey_PreSwitchSpecialMove(Move move, MakeMoveGa
}
else
{
PieceBitBoards[move.CapturedPiece()].SetBit(targetSquare);
PieceBitBoards[capturedPiece].SetBit(targetSquare);
OccupancyBitBoards[oppositeSide].SetBit(targetSquare);
}
}
Expand Down Expand Up @@ -1228,6 +1230,7 @@ public void UnmakeMove_WithZobristKey_SwitchSpecialMove(Move move, MakeMoveGameS
int targetSquare = move.TargetSquare();
int piece = move.Piece();
int promotedPiece = move.PromotedPiece();
int capturedPiece = Board[targetSquare];

var newPiece = piece;
if (promotedPiece != default)
Expand All @@ -1247,7 +1250,7 @@ public void UnmakeMove_WithZobristKey_SwitchSpecialMove(Move move, MakeMoveGameS
{
if (move.IsCapture())
{
PieceBitBoards[move.CapturedPiece()].SetBit(targetSquare);
PieceBitBoards[capturedPiece].SetBit(targetSquare);
OccupancyBitBoards[oppositeSide].SetBit(targetSquare);
}

Expand Down Expand Up @@ -1748,7 +1751,7 @@ internal static void GeneratePieceMoves(ref int localIndex, Move[] movePool, int

if (position.OccupancyBitBoards[(int)Side.Both].GetBit(targetSquare))
{
movePool[localIndex++] = MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece, capturedPiece: 1);
movePool[localIndex++] = MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece);
}
else if (!capturesOnly)
{
Expand Down
13 changes: 11 additions & 2 deletions src/Lynx.Benchmark/MakeUnmakeMove_integration_Benchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ public struct MakeMovePosition

public BitBoard[] OccupancyBitBoards { get; }

public int[] Board { get; }

public Side Side { get; private set; }

public BoardSquare EnPassant { get; private set; }
Expand All @@ -309,11 +311,12 @@ public MakeMovePosition(string fen) : this(FENParser.ParseFEN(fen))
{
}

public MakeMovePosition((BitBoard[] PieceBitBoards, BitBoard[] OccupancyBitBoards, Side Side, byte Castle, BoardSquare EnPassant,
public MakeMovePosition((BitBoard[] PieceBitBoards, BitBoard[] OccupancyBitBoards, int[] board, Side Side, byte Castle, BoardSquare EnPassant,
int HalfMoveClock/*, int FullMoveCounter*/) parsedFEN)
{
PieceBitBoards = parsedFEN.PieceBitBoards;
OccupancyBitBoards = parsedFEN.OccupancyBitBoards;
Board = parsedFEN.board;
Side = parsedFEN.Side;
Castle = parsedFEN.Castle;
EnPassant = parsedFEN.EnPassant;
Expand All @@ -335,6 +338,9 @@ public MakeMovePosition(MakeMovePosition position)
OccupancyBitBoards = new BitBoard[3];
Array.Copy(position.OccupancyBitBoards, OccupancyBitBoards, position.OccupancyBitBoards.Length);

Board = new int[64];
Array.Copy(position.Board, Board, position.Board.Length);

Side = position.Side;
Castle = position.Castle;
EnPassant = position.EnPassant;
Expand All @@ -356,6 +362,9 @@ public MakeMovePosition(MakeMovePosition position, bool nullMove)
OccupancyBitBoards = new BitBoard[3];
Array.Copy(position.OccupancyBitBoards, OccupancyBitBoards, position.OccupancyBitBoards.Length);

Board = new int[64];
Array.Copy(position.Board, Board, position.Board.Length);

Side = (Side)Utils.OppositeSide(position.Side);
Castle = position.Castle;
EnPassant = BoardSquare.noSquare;
Expand Down Expand Up @@ -1615,7 +1624,7 @@ internal static void GeneratePieceMoves(ref int localIndex, Move[] movePool, int

if (position.OccupancyBitBoards[(int)Side.Both].GetBit(targetSquare))
{
movePool[localIndex++] = MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece, 1);
movePool[localIndex++] = MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece);
}
else if (!capturesOnly)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Lynx.Benchmark/MoveGeneratorParallel_Benchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ internal static IEnumerable<Move> GeneratePieceMoves(int piece, Position positio

if (position.OccupancyBitBoards[(int)Side.Both].GetBit(targetSquare))
{
yield return MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece, 1);
yield return MoveExtensions.EncodeCapture(sourceSquare, targetSquare, piece);
}
else if (!capturesOnly)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Lynx.Benchmark/Move_UCIString_Benchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public class Move_UCIString_Benchmark : BaseBenchmark
MoveExtensions.EncodeLongCastle(Constants.BlackKingSourceSquare, Constants.BlackLongCastleKingSquare, (int)Piece.k),
MoveExtensions.Encode((int)BoardSquare.e2, (int)BoardSquare.e4, (int)Piece.P),
MoveExtensions.EncodePromotion((int)BoardSquare.e7, (int)BoardSquare.e8, (int)Piece.p, promotedPiece: (int)Piece.q),
MoveExtensions.EncodePromotion((int)BoardSquare.a7, (int)BoardSquare.b8, (int)Piece.p, promotedPiece: (int)Piece.n, capturedPiece: (int)Piece.B),
MoveExtensions.EncodeCapture((int)BoardSquare.a8, (int)BoardSquare.h1, (int)Piece.B, capturedPiece: (int)Piece.b),
MoveExtensions.EncodePromotionWithCapture((int)BoardSquare.a7, (int)BoardSquare.b8, (int)Piece.p, promotedPiece: (int)Piece.n),
MoveExtensions.EncodeCapture((int)BoardSquare.a8, (int)BoardSquare.h1, (int)Piece.B),
MoveExtensions.EncodeCapture((int)BoardSquare.a8, (int)BoardSquare.h1, (int)Piece.B),
MoveExtensions.EncodeEnPassant((int)BoardSquare.e5, (int)BoardSquare.d6, (int)Piece.P)
];
Expand Down
20 changes: 12 additions & 8 deletions src/Lynx/FENParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Buffers;
using System.Runtime.CompilerServices;

using ParseResult = (ulong[] PieceBitBoards, ulong[] OccupancyBitBoards, Lynx.Model.Side Side, byte Castle, Lynx.Model.BoardSquare EnPassant,
using ParseResult = (ulong[] PieceBitBoards, ulong[] OccupancyBitBoards, int[] board, Lynx.Model.Side Side, byte Castle, Lynx.Model.BoardSquare EnPassant,
int HalfMoveClock/*, int FullMoveCounter*/);

namespace Lynx;
Expand All @@ -19,6 +19,8 @@ public static ParseResult ParseFEN(ReadOnlySpan<char> fen)

var pieceBitBoards = ArrayPool<BitBoard>.Shared.Rent(12);
var occupancyBitBoards = ArrayPool<BitBoard>.Shared.Rent(3);
var board = ArrayPool<int>.Shared.Rent(64);
Array.Fill(board, (int)Piece.None);

bool success;
Side side = Side.Both;
Expand All @@ -28,7 +30,7 @@ public static ParseResult ParseFEN(ReadOnlySpan<char> fen)

try
{
success = ParseBoard(fen, pieceBitBoards, occupancyBitBoards);
success = ParseBoard(fen, pieceBitBoards, occupancyBitBoards, board);

var unparsedStringAsSpan = fen[fen.IndexOf(' ')..];
Span<Range> parts = stackalloc Range[5];
Expand Down Expand Up @@ -63,12 +65,12 @@ public static ParseResult ParseFEN(ReadOnlySpan<char> fen)
}

return success
? (pieceBitBoards, occupancyBitBoards, side, castle, enPassant, halfMoveClock/*, fullMoveCounter*/)
? (pieceBitBoards, occupancyBitBoards, board, side, castle, enPassant, halfMoveClock/*, fullMoveCounter*/)
: throw new AssertException($"Error parsing {fen.ToString()}");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool ParseBoard(ReadOnlySpan<char> fen, BitBoard[] pieceBitBoards, BitBoard[] occupancyBitBoards)
private static bool ParseBoard(ReadOnlySpan<char> fen, BitBoard[] pieceBitBoards, BitBoard[] occupancyBitBoards, int[] board)
{
bool success = true;
var rankIndex = 0;
Expand All @@ -83,7 +85,7 @@ private static bool ParseBoard(ReadOnlySpan<char> fen, BitBoard[] pieceBitBoards
{
var match = fen[..end];

ParseBoardSection(pieceBitBoards, rankIndex, match
ParseBoardSection(pieceBitBoards, board, rankIndex, match
#if DEBUG
, ref success
#endif
Expand All @@ -95,7 +97,7 @@ private static bool ParseBoard(ReadOnlySpan<char> fen, BitBoard[] pieceBitBoards
++rankIndex;
}

ParseBoardSection(pieceBitBoards, rankIndex, fen[..fen.IndexOf(' ')]
ParseBoardSection(pieceBitBoards, board, rankIndex, fen[..fen.IndexOf(' ')]
#if DEBUG
, ref success
#endif
Expand All @@ -104,7 +106,7 @@ private static bool ParseBoard(ReadOnlySpan<char> fen, BitBoard[] pieceBitBoards

return success;

static void ParseBoardSection(BitBoard[] pieceBitBoards, int rankIndex, ReadOnlySpan<char> boardfenSection
static void ParseBoardSection(BitBoard[] pieceBitBoards, int[] board, int rankIndex, ReadOnlySpan<char> boardfenSection
#if DEBUG
, ref bool success
#endif
Expand Down Expand Up @@ -135,7 +137,9 @@ static void ParseBoardSection(BitBoard[] pieceBitBoards, int rankIndex, ReadOnly

if (piece != Piece.None)
{
pieceBitBoards[(int)piece] = pieceBitBoards[(int)piece].SetBit(BitBoardExtensions.SquareIndex(rankIndex, fileIndex));
var square = BitBoardExtensions.SquareIndex(rankIndex, fileIndex);
pieceBitBoards[(int)piece] = pieceBitBoards[(int)piece].SetBit(square);
board[square] = (int)piece;
++fileIndex;
}
else
Expand Down
5 changes: 4 additions & 1 deletion src/Lynx/Model/GameState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ public readonly struct GameState
{
public readonly long ZobristKey;

public readonly int CapturedPiece;

public readonly BoardSquare EnPassant;

public readonly byte Castle;

public GameState(long zobristKey, BoardSquare enpassant, byte castle)
public GameState(long zobristKey, int capturedPiece, BoardSquare enpassant, byte castle)
{
ZobristKey = zobristKey;
CapturedPiece = capturedPiece;
EnPassant = enpassant;
Castle = castle;
}
Expand Down
Loading
Loading