Skip to content

Commit

Permalink
Simplified Position fields (liamt19#54)
Browse files Browse the repository at this point in the history
bench: 5609869
  • Loading branch information
liamt19 authored Jul 18, 2024
1 parent e528e8a commit 2effd02
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 150 deletions.
58 changes: 8 additions & 50 deletions Logic/Core/MoveGeneration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,35 +223,27 @@ int GenCastlingMoves(ScoredMove* list, int size)
{
if (ToMove == White && (ourKing == E1 || IsChess960))
{
if (State->CastleStatus.HasFlag(CastlingStatus.WK)
&& (occ & CastlingRookPaths[(int)CastlingStatus.WK]) == 0
&& (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)CastlingStatus.WK]] & us) != 0)
if (CanCastle(occ, us, CastlingStatus.WK))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.WK]);
}

if (State->CastleStatus.HasFlag(CastlingStatus.WQ)
&& (occ & CastlingRookPaths[(int)CastlingStatus.WQ]) == 0
&& (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)CastlingStatus.WQ]] & us) != 0)
if (CanCastle(occ, us, CastlingStatus.WQ))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.WQ]);
}
}
else if (ToMove == Black && (ourKing == E8 || IsChess960))
{
if (State->CastleStatus.HasFlag(CastlingStatus.BK)
&& (occ & CastlingRookPaths[(int)CastlingStatus.BK]) == 0
&& (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)CastlingStatus.BK]] & us) != 0)
if (CanCastle(occ, us, CastlingStatus.BK))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.BK]);
}

if (State->CastleStatus.HasFlag(CastlingStatus.BQ)
&& (occ & CastlingRookPaths[(int)CastlingStatus.BQ]) == 0
&& (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)CastlingStatus.BQ]] & us) != 0)
if (CanCastle(occ, us, CastlingStatus.BQ))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.BQ]);
Expand Down Expand Up @@ -368,32 +360,6 @@ public int GenLegal(Span<ScoredMove> legal)
}


/// <summary>
/// <inheritdoc cref="GenPseudoLegal(ScoredMove*)"/>
/// </summary>
public int GenPseudoLegal(Span<ScoredMove> pseudo)
{
fixed (ScoredMove* ptr = pseudo)
{
return GenPseudoLegal(ptr);
}

}


/// <summary>
/// <inheritdoc cref="GenAll{GenType}(ScoredMove*, int)"/>
/// </summary>
public int GenAll<GenType>(Span<ScoredMove> list, int size = 0) where GenType : MoveGenerationType
{
fixed (ScoredMove* ptr = list)
{
return GenAll<GenType>(ptr, size);
}
}



public int GenPseudoLegalQS(ScoredMove* pseudo, int ttDepth)
{
return (State->Checkers != 0) ? GenAll<GenEvasions>(pseudo) :
Expand Down Expand Up @@ -445,35 +411,27 @@ int GenCastlingMoves(ScoredMove* list, int size)
{
if (ToMove == White && (ourKing == E1 || IsChess960))
{
if (State->CastleStatus.HasFlag(CastlingStatus.WK)
&& !CastlingImpeded(us, CastlingStatus.WK)
&& HasCastlingRook(us, CastlingStatus.WK))
if (CanCastle(occ, us, CastlingStatus.WK))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.WK]);
}

if (State->CastleStatus.HasFlag(CastlingStatus.WQ)
&& !CastlingImpeded(us, CastlingStatus.WQ)
&& HasCastlingRook(us, CastlingStatus.WQ))
if (CanCastle(occ, us, CastlingStatus.WQ))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.WQ]);
}
}
else if (ToMove == Black && (ourKing == E8 || IsChess960))
{
if (State->CastleStatus.HasFlag(CastlingStatus.BK)
&& !CastlingImpeded(us, CastlingStatus.BK)
&& HasCastlingRook(us, CastlingStatus.BK))
if (CanCastle(occ, us, CastlingStatus.BK))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.BK]);
}

if (State->CastleStatus.HasFlag(CastlingStatus.BQ)
&& !CastlingImpeded(us, CastlingStatus.BQ)
&& HasCastlingRook(us, CastlingStatus.BQ))
if (CanCastle(occ, us, CastlingStatus.BQ))
{
ref Move m = ref list[size++].Move;
m.SetNewCastle(ourKing, CastlingRookSquares[(int)CastlingStatus.BQ]);
Expand Down
137 changes: 37 additions & 100 deletions Logic/Core/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ public unsafe partial class Position
public Bitboard bb;

/// <summary>
/// The second number in the FEN, which starts at 1 and increases every time black moves.
/// The number of moves that have been made so far since this Position was created.
/// <br></br>
/// Only used to easily keep track of how far along the StateStack we currently are.
/// </summary>
public int FullMoves = 1;
public int ToMove;

public bool InCheck;
public bool InDoubleCheck;
public int GamePly = 0;

/// <summary>
/// Set to the index of the piece giving check,
/// or the piece with the lowest square index if there are two pieces giving check.
/// The second number in the FEN, which starts at 1 and increases every time black moves.
/// </summary>
public int idxChecker;
public int FullMoves = 1;

public int ToMove;

public bool Checked => InCheck || InDoubleCheck;
public bool InCheck => popcount(State->Checkers) == 1;
public bool InDoubleCheck => popcount(State->Checkers) == 2;
public bool Checked => popcount(State->Checkers) != 0;

public ulong Hash => State->Hash;

Expand All @@ -39,35 +39,19 @@ public unsafe partial class Position
/// </summary>
private const int StateStackSize = 2048;

private readonly StateInfo* _stateBlock;

/// <summary>
/// A pointer to the beginning of the StateStack, which is used to make sure we don't try to access the StateStack at negative indices.
/// </summary>
private readonly StateInfo* _SentinelStart;
private readonly StateInfo* _SentinelEnd;

public readonly StateInfo* StartingState;
private readonly StateInfo* EndState;

public StateInfo* StartingState => _SentinelStart;

/// <summary>
/// A pointer to this Position's current <see cref="StateInfo"/> object, which corresponds to the StateStack[GamePly]
/// </summary>
public StateInfo* State;
public StateInfo* NextState => (State + 1);



private readonly Accumulator* _accumulatorBlock;


/// <summary>
/// The number of moves that have been made so far since this Position was created.
/// <br></br>
/// Only used to easily keep track of how far along the StateStack we currently are.
/// </summary>
public int GamePly = 0;

/// <summary>
/// The SearchThread that owns this Position instance.
/// </summary>
Expand All @@ -78,23 +62,33 @@ public unsafe partial class Position
/// This must be true if this position object is being used in a search,
/// but for purely perft this should be disabled for performance.
/// </summary>
public readonly bool UpdateNN;
private readonly bool UpdateNN;


public int[] CastlingRookSquares;
public ulong[] CastlingRookPaths;
private readonly int[] CastlingRookSquares;
private readonly ulong[] CastlingRookPaths;

public bool IsChess960 = false;


[MethodImpl(Inline)]
public bool CanCastle(ulong boardOcc, ulong ourOcc, CastlingStatus cr)
{
return State->CastleStatus.HasFlag(cr)
&& !CastlingImpeded(boardOcc, cr)
&& HasCastlingRook(ourOcc, cr);
}

[MethodImpl(Inline)]
public bool CastlingImpeded(ulong occ, CastlingStatus cr) => (occ & CastlingRookPaths[(int)cr]) != 0;
private bool CastlingImpeded(ulong boardOcc, CastlingStatus cr) => (boardOcc & CastlingRookPaths[(int)cr]) != 0;

[MethodImpl(Inline)]
public bool HasCastlingRook(ulong us, CastlingStatus cr) => (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)cr]] & us) != 0;
private bool HasCastlingRook(ulong ourOcc, CastlingStatus cr) => (bb.Pieces[Rook] & SquareBB[CastlingRookSquares[(int)cr]] & ourOcc) != 0;

[MethodImpl(Inline)]
public bool HasNonPawnMaterial(int pc) => (((bb.Occupancy ^ bb.Pieces[Pawn] ^ bb.Pieces[King]) & bb.Colors[pc]) != 0);


/// <summary>
/// Creates a new Position object and loads the provided FEN.
/// <br></br>
Expand All @@ -117,11 +111,10 @@ public Position(string fen = InitialFEN, bool createAccumulators = true, SearchT

this.bb = new Bitboard();

_stateBlock = AlignedAllocZeroed<StateInfo>(StateStackSize);
StartingState = AlignedAllocZeroed<StateInfo>(StateStackSize);

_SentinelStart = &_stateBlock[0];
_SentinelEnd = &_stateBlock[StateStackSize - 1];
State = &_stateBlock[0];
EndState = &StartingState[StateStackSize - 1];
State = &StartingState[0];

if (UpdateNN)
{
Expand All @@ -131,8 +124,8 @@ public Position(string fen = InitialFEN, bool createAccumulators = true, SearchT
_accumulatorBlock = AlignedAllocZeroed<Accumulator>(StateStackSize);
for (int i = 0; i < StateStackSize; i++)
{
(_stateBlock + i)->Accumulator = _accumulatorBlock + i;
*(_stateBlock + i)->Accumulator = new Accumulator();
(StartingState + i)->Accumulator = _accumulatorBlock + i;
*(StartingState + i)->Accumulator = new Accumulator();
}
}

Expand All @@ -158,14 +151,14 @@ public Position(string fen = InitialFEN, bool createAccumulators = true, SearchT
// Free each accumulator, then the block
for (int i = 0; i < StateStackSize; i++)
{
var acc = *(_SentinelStart + i)->Accumulator;
var acc = *(StartingState + i)->Accumulator;
acc.Dispose();
}

NativeMemory.AlignedFree((void*)_accumulatorBlock);
}

NativeMemory.AlignedFree((void*)_stateBlock);
NativeMemory.AlignedFree((void*)StartingState);
}

/// <summary>
Expand Down Expand Up @@ -365,24 +358,6 @@ public void MakeMove(Move move)
ToMove = Not(ToMove);

State->Checkers = bb.AttackersTo(State->KingSquares[theirColor], bb.Occupancy) & bb.Colors[ourColor];
switch (popcount(State->Checkers))
{
case 0:
InCheck = false;
InDoubleCheck = false;
idxChecker = SquareNB;
break;
case 1:
InCheck = true;
InDoubleCheck = false;
idxChecker = lsb(State->Checkers);
break;
case 2:
InCheck = false;
InDoubleCheck = true;
idxChecker = lsb(State->Checkers);
break;
}

SetCheckInfo();
}
Expand Down Expand Up @@ -445,26 +420,6 @@ public void UnmakeMove(Move move)

State--;

switch (popcount(State->Checkers))
{
case 0:
InCheck = false;
InDoubleCheck = false;
idxChecker = SquareNB;
break;
case 1:
InCheck = true;
InDoubleCheck = false;
idxChecker = lsb(State->Checkers);
break;
case 2:
InCheck = false;
InDoubleCheck = true;
idxChecker = lsb(State->Checkers);
break;
}


ToMove = Not(ToMove);
}

Expand Down Expand Up @@ -554,24 +509,6 @@ public void DoCastling(int ourColor, int from, int to, bool undo = false)
public void SetState()
{
State->Checkers = bb.AttackersTo(State->KingSquares[ToMove], bb.Occupancy) & bb.Colors[Not(ToMove)];
switch (popcount(State->Checkers))
{
case 0:
InCheck = false;
InDoubleCheck = false;
idxChecker = SquareNB;
break;
case 1:
InCheck = true;
InDoubleCheck = false;
idxChecker = lsb(State->Checkers);
break;
case 2:
InCheck = false;
InDoubleCheck = true;
idxChecker = lsb(State->Checkers);
break;
}

SetCheckInfo();

Expand Down Expand Up @@ -747,7 +684,7 @@ public bool IsLegal(Move move, int ourKing, int theirKing, ulong pinnedPieces)
return ((bb.AttackersTo(moveTo, bb.Occupancy ^ SquareBB[moveFrom]) & bb.Colors[theirColor]) | (NeighborsMask[moveTo] & SquareBB[theirKing])) == 0;
}

int checker = idxChecker;
int checker = lsb(State->Checkers);
if (((LineBB[ourKing][checker] & SquareBB[moveTo]) != 0)
|| (move.GetEnPassant() && GetIndexFile(moveTo) == GetIndexFile(checker)))
{
Expand Down Expand Up @@ -885,7 +822,7 @@ public bool IsThreefoldRepetition()
}
}

if ((temp - 1) == _SentinelStart || (temp - 2) == _SentinelStart)
if ((temp - 1) == StartingState || (temp - 2) == StartingState)
{
break;
}
Expand Down Expand Up @@ -1253,7 +1190,7 @@ public string GetFEN()

public override string ToString()
{
return PrintBoard(bb);
return $"{PrintBoard(bb)}\r\n\r\nHash: {Hash}";
}

}
Expand Down

0 comments on commit 2effd02

Please sign in to comment.