Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
constexpr Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
constexpr Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
// Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
// situations. Description of the algorithm in the following paper:
// Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
// situations. Description of the algorithm in the following paper:
// First and second hash functions for indexing the cuckoo tables
inline int H1(Key h) { return h & 0x1fff; }
// First and second hash functions for indexing the cuckoo tables
inline int H1(Key h) { return h & 0x1fff; }
// Prepare the cuckoo tables
std::memset(cuckoo, 0, sizeof(cuckoo));
std::memset(cuckooMove, 0, sizeof(cuckooMove));
// Prepare the cuckoo tables
std::memset(cuckoo, 0, sizeof(cuckoo));
std::memset(cuckooMove, 0, sizeof(cuckooMove));
- si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), si->pinners[BLACK]);
- si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), si->pinners[WHITE]);
+ st->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), st->pinners[BLACK]);
+ st->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), st->pinners[WHITE]);
- si->checkSquares[PAWN] = pawn_attacks_bb(~sideToMove, ksq);
- si->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
- si->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
- si->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
- si->checkSquares[QUEEN] = si->checkSquares[BISHOP] | si->checkSquares[ROOK];
- si->checkSquares[KING] = 0;
+ st->checkSquares[PAWN] = pawn_attacks_bb(~sideToMove, ksq);
+ st->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
+ st->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
+ st->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
+ st->checkSquares[QUEEN] = st->checkSquares[BISHOP] | st->checkSquares[ROOK];
+ st->checkSquares[KING] = 0;
/// The function is only used when a new position is set up, and to verify
/// the correctness of the StateInfo data when running in debug mode.
/// The function is only used when a new position is set up, and to verify
/// the correctness of the StateInfo data when running in debug mode.
- si->key = si->materialKey = 0;
- si->pawnKey = Zobrist::noPawns;
- si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
- si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
+ st->key = st->materialKey = 0;
+ st->pawnKey = Zobrist::noPawns;
+ st->nonPawnMaterial[WHITE] = st->nonPawnMaterial[BLACK] = VALUE_ZERO;
+ st->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
: MoveList<NON_EVASIONS>(*this).contains(m);
// Is not a promotion, so promotion piece must be empty
: MoveList<NON_EVASIONS>(*this).contains(m);
// Is not a promotion, so promotion piece must be empty
// If the 'from' square is not occupied by a piece belonging to the side to
// move, the move is obviously not legal.
// If the 'from' square is not occupied by a piece belonging to the side to
// move, the move is obviously not legal.
// Update material hash key and prefetch access to materialTable
k ^= Zobrist::psq[captured][capsq];
st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
// Update material hash key and prefetch access to materialTable
k ^= Zobrist::psq[captured][capsq];
st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
// Calculate the repetition info. It is the ply distance from the previous
// occurrence of the same position, negative in the 3-fold case, or zero
// Calculate the repetition info. It is the ply distance from the previous
// occurrence of the same position, negative in the 3-fold case, or zero
st->dirtyPiece.dirty_num = 0;
st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
st->dirtyPiece.dirty_num = 0;
st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
/// SEE value of move is greater or equal to the given threshold. We'll use an
/// algorithm similar to alpha-beta pruning with a null window.
/// SEE value of move is greater or equal to the given threshold. We'll use an
/// algorithm similar to alpha-beta pruning with a null window.
- Bitboard occupied = pieces() ^ from ^ to;
- Color stm = color_of(piece_on(from));
+ assert(color_of(piece_on(from)) == sideToMove);
+ occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
+ Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
int res = 1;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
int res = 1;
// Don't allow pinned pieces to attack as long as there are
// pinners on their original square.
if (pinners(~stm) & occupied)
// Don't allow pinned pieces to attack as long as there are
// pinners on their original square.
if (pinners(~stm) & occupied)
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(KNIGHT)))
{
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(KNIGHT)))
{
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(ROOK)))
{
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(ROOK)))
{
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
}
else if ((bb = stmAttackers & pieces(QUEEN)))
{
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
}
else if ((bb = stmAttackers & pieces(QUEEN)))
{
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
}
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
}
- StateInfo si = *st;
- ASSERT_ALIGNED(&si, Eval::NNUE::CacheLineSize);
-
- set_state(&si);
- if (std::memcmp(&si, st, sizeof(StateInfo)))
- assert(0 && "pos_is_ok: State");