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;
}
/// Position::set_state() computes the hash keys of the position, and other
/// data that once computed is updated incrementally as moves are made.
}
/// Position::set_state() computes the hash keys of the position, and other
/// data that once computed is updated incrementally as moves are made.
- 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->nonPawnMaterial[WHITE] = st->nonPawnMaterial[BLACK] = VALUE_ZERO;
+ st->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
- if (type_of(pc) == PAWN)
- si->pawnKey ^= Zobrist::psq[pc][s];
-
- else if (type_of(pc) != KING)
- si->nonPawnMaterial[color_of(pc)] += PieceValue[MG][pc];
+ if (type_of(pc) != KING && type_of(pc) != PAWN)
+ st->nonPawnMaterial[color_of(pc)] += PieceValue[MG][pc];
: 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.
- if ( (blockers_for_king(~sideToMove) & from)
- && !aligned(from, to, square<KING>(~sideToMove)))
- return true;
+ if (blockers_for_king(~sideToMove) & from)
+ return !aligned(from, to, square<KING>(~sideToMove))
+ || type_of(m) == CASTLING;
assert(piece_on(to) == NO_PIECE);
assert(piece_on(capsq) == make_piece(them, PAWN));
}
assert(piece_on(to) == NO_PIECE);
assert(piece_on(capsq) == make_piece(them, PAWN));
}
- if (Eval::useNNUE)
- {
- dp.dirty_num = 2; // 1 piece moved, 1 piece captured
- dp.piece[1] = captured;
- dp.from[1] = capsq;
- dp.to[1] = SQ_NONE;
- }
+ dp.dirty_num = 2; // 1 piece moved, 1 piece captured
+ dp.piece[1] = captured;
+ dp.from[1] = capsq;
+ dp.to[1] = SQ_NONE;
// 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]];
- if (Eval::useNNUE)
- {
- // Promoting pawn to SQ_NONE, promoted piece from SQ_NONE
- dp.to[0] = SQ_NONE;
- dp.piece[dp.dirty_num] = promotion;
- dp.from[dp.dirty_num] = SQ_NONE;
- dp.to[dp.dirty_num] = to;
- dp.dirty_num++;
- }
+ // Promoting pawn to SQ_NONE, promoted piece from SQ_NONE
+ dp.to[0] = SQ_NONE;
+ dp.piece[dp.dirty_num] = promotion;
+ dp.from[dp.dirty_num] = SQ_NONE;
+ dp.to[dp.dirty_num] = to;
+ dp.dirty_num++;
st->materialKey ^= Zobrist::psq[promotion][pieceCount[promotion]-1]
^ Zobrist::psq[pc][pieceCount[pc]];
st->materialKey ^= Zobrist::psq[promotion][pieceCount[promotion]-1]
^ Zobrist::psq[pc][pieceCount[pc]];
// 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
rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
{
auto& dp = st->dirtyPiece;
dp.piece[0] = make_piece(us, KING);
{
auto& dp = st->dirtyPiece;
dp.piece[0] = make_piece(us, KING);
/// 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.
Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
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));
}
/// Position::is_draw() tests whether the position is drawn by 50-move rule
/// or by repetition. It does not detect stalemates.
/// Position::is_draw() tests whether the position is drawn by 50-move rule
/// or by repetition. It does not detect stalemates.
- 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");