Skip to content

Commit

Permalink
Fix Stack overflow in games with more than 256 moves (#293)
Browse files Browse the repository at this point in the history
Bench: 6645600
  • Loading branch information
PGG106 authored Jan 2, 2024
1 parent 44f57de commit 4a081e7
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ void parse_moves(const std::string& moves, S_Board* pos) {
// parse next move
int move = ParseMove(move_tokens[i], pos);
// make move on the chess board
MakeMove(move, pos);
MakeUCIMove(move, pos);
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ struct S_Board {
// Occupancies bitboards based on piece and side
Bitboard bitboards[12] = {};
Bitboard occupancies[2] = {};
NNUE::accumulator accumulator = {};
// Previous values of the nnue accumulators. always empty at the start of search
std::vector<NNUE::accumulator> accumulatorStack = {};
Bitboard checkers;
Bitboard checkMask = fullCheckmask;

Expand Down
109 changes: 109 additions & 0 deletions src/makemove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,115 @@ void inline HashKey(S_Board* pos, ZobristKey key) {
pos->posKey ^= key;
}

// make move on chess board
void MakeUCIMove(const int move, S_Board* pos) {

// Store position key in the array of searched position
pos->played_positions.emplace_back(pos->posKey);

// parse move
const int sourceSquare = From(move);
const int targetSquare = To(move);
const int piece = Piece(move);
const int promotedPiece = GetPiece(getPromotedPiecetype(move), pos->side);
// parse move flag
const bool capture = IsCapture(move);
const bool doublePush = isDP(move);
const bool enpass = isEnpassant(move);
const bool castling = IsCastle(move);
const bool promotion = isPromo(move);
// increment fifty move rule counter
pos->fiftyMove++;
pos->plyFromNull++;
const int NORTH = pos->side == WHITE ? 8 : -8;

// if a pawn was moved reset the 50 move rule counter
if (GetPieceType(piece) == PAWN)
pos->fiftyMove = 0;

// handle enpassant captures
if (enpass) {
ClearPiece(GetPiece(PAWN, pos->side ^ 1), targetSquare + NORTH, pos);
}
// handling capture moves
else if (capture) {
const int pieceCap = pos->pieces[targetSquare];
assert(pieceCap != EMPTY);
ClearPiece(pieceCap, targetSquare, pos);

// a capture was played so reset 50 move rule counter
pos->fiftyMove = 0;
}

// increment ply counters
pos->hisPly++;
// Remove the piece fom the square it moved from
ClearPiece(piece, sourceSquare, pos);
// Set the piece to the destination square, if it was a promotion we directly set the promoted piece
AddPiece(promotion ? promotedPiece : piece, targetSquare, pos);

// Reset EP square
if (GetEpSquare(pos) != no_sq)
HashKey(pos, enpassant_keys[GetEpSquare(pos)]);

// reset enpassant square
pos->enPas = no_sq;

// handle double pawn push
if (doublePush) {
pos->enPas = targetSquare + NORTH;
// hash enpassant
HashKey(pos, enpassant_keys[GetEpSquare(pos)]);
}

// handle castling moves
if (castling) {
// switch target square
switch (targetSquare) {
// white castles king side
case (g1):
// move H rook
MovePiece(WR, h1, f1, pos);
break;

// white castles queen side
case (c1):
// move A rook
MovePiece(WR, a1, d1, pos);
break;

// black castles king side
case (g8):
// move H rook
MovePiece(BR, h8, f8, pos);
break;

// black castles queen side
case (c8):
// move A rook
MovePiece(BR, a8, d8, pos);
break;
}
}

UpdateCastlingPerms(pos, sourceSquare, targetSquare);

// change side
pos->ChangeSide();
// Xor the new side into the key
HashKey(pos, SideKey);
// Speculative prefetch of the TT entry
pos->checkers = GetCheckersBB(pos, pos->side);
// If we are in check get the squares between the checking piece and the king
if (pos->checkers) {
const int kingSquare = KingSQ(pos, pos->side);
const int pieceLocation = GetLsbIndex(pos->checkers);
pos->checkMask = (1ULL << pieceLocation) | RayBetween(pieceLocation, kingSquare);
}
else
pos->checkMask = fullCheckmask;
}

// make move on chess board
void MakeMove(const int move, S_Board* pos) {
// Store position variables for rollback purposes
Expand Down
2 changes: 2 additions & 0 deletions src/makemove.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ void UnmakeMove(const int move, S_Board* pos);
void MakeNullMove(S_Board* pos);
// Reverts the previously played null move
void TakeNullMove(S_Board* pos);
// Makes a move without setting up the variables to ever reverse it, should only be used on moves that come directly from uci
void MakeUCIMove(const int move, S_Board* pos);
2 changes: 1 addition & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <cstdint>

#define NAME "Alexandria-5.1.11"
#define NAME "Alexandria-5.1.11.1"

// define bitboard data type
using Bitboard = uint64_t;
Expand Down

0 comments on commit 4a081e7

Please sign in to comment.