// the move is made.
if (type_of(m) == ENPASSANT)
{
- Color them = ~us;
- Square to = to_sq(m);
- Square capsq = to + pawn_push(them);
Square ksq = king_square(us);
- Bitboard b = (pieces() ^ from ^ capsq) | to;
+ Square to = to_sq(m);
+ Square capsq = to - pawn_push(us);
+ Bitboard occ = (pieces() ^ from ^ capsq) | to;
assert(to == ep_square());
assert(moved_piece(m) == make_piece(us, PAWN));
- assert(piece_on(capsq) == make_piece(them, PAWN));
+ assert(piece_on(capsq) == make_piece(~us, PAWN));
assert(piece_on(to) == NO_PIECE);
- return !(attacks_bb< ROOK>(ksq, b) & pieces(them, QUEEN, ROOK))
- && !(attacks_bb<BISHOP>(ksq, b) & pieces(them, QUEEN, BISHOP));
+ return !(attacks_bb< ROOK>(ksq, occ) & pieces(~us, QUEEN, ROOK))
+ && !(attacks_bb<BISHOP>(ksq, occ) & pieces(~us, QUEEN, BISHOP));
}
// If the moving piece is a king, check whether the destination
{
assert(pc == make_piece(us, KING));
- bool kingSide = to > from;
- Square rfrom = to; // Castling is encoded as "king captures friendly rook"
- Square rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
- to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
- captured = NO_PIECE_TYPE;
-
- do_castling(from, to, rfrom, rto);
+ Square rfrom, rto;
+ do_castling<true>(from, to, rfrom, rto);
+ captured = NO_PIECE_TYPE;
st->psq += psq[us][ROOK][rto] - psq[us][ROOK][rfrom];
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
}
if (type_of(m) == CASTLING)
{
- bool kingSide = to > from;
- Square rfrom = to; // Castling is encoded as "king captures friendly rook"
- Square rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
- to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
+ Square rfrom, rto;
+ do_castling<false>(from, to, rfrom, rto);
+
captured = NO_PIECE_TYPE;
pt = KING;
- do_castling(to, from, rto, rfrom);
}
else
move_piece(to, from, us, pt); // Put the piece back at the source square
/// Position::do_castling() is a helper used to do/undo a castling move. This
/// is a bit tricky, especially in Chess960.
+template<bool Do>
+void Position::do_castling(Square from, Square& to, Square& rfrom, Square& rto) {
-void Position::do_castling(Square kfrom, Square kto, Square rfrom, Square rto) {
+ bool kingSide = to > from;
+ rfrom = to; // Castling is encoded as "king captures friendly rook"
+ rto = relative_square(sideToMove, kingSide ? SQ_F1 : SQ_D1);
+ to = relative_square(sideToMove, kingSide ? SQ_G1 : SQ_C1);
// Remove both pieces first since squares could overlap in Chess960
- remove_piece(kfrom, sideToMove, KING);
- remove_piece(rfrom, sideToMove, ROOK);
- board[kfrom] = board[rfrom] = NO_PIECE; // Since remove_piece doesn't do it for us
- put_piece(kto, sideToMove, KING);
- put_piece(rto, sideToMove, ROOK);
+ remove_piece(Do ? from : to, sideToMove, KING);
+ remove_piece(Do ? rfrom : rto, sideToMove, ROOK);
+ board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
+ put_piece(Do ? to : from, sideToMove, KING);
+ put_piece(Do ? rto : rfrom, sideToMove, ROOK);
}
int dummy, *step = failedStep ? failedStep : &dummy;
- // What features of the position should be verified?
+ // Which parts of the position should be verified?
const bool all = false;
const bool testBitboards = all || false;
+ const bool testState = all || false;
const bool testKingCount = all || false;
const bool testKingCapture = all || false;
- const bool testState = all || false;
- const bool testCheckerCount = all || false;
const bool testPieceCounts = all || false;
const bool testPieceList = all || false;
const bool testCastlingSquares = all || false;
if ((*step)++, ep_square() != SQ_NONE && relative_rank(sideToMove, ep_square()) != RANK_6)
return false;
- if ((*step)++, testKingCount)
- if ( std::count(board, board + SQUARE_NB, W_KING) != 1
- || std::count(board, board + SQUARE_NB, B_KING) != 1)
- return false;
-
- if ((*step)++, testKingCapture)
- if (attackers_to(king_square(~sideToMove)) & pieces(sideToMove))
- return false;
-
if ((*step)++, testBitboards)
{
// The intersection of the white and black pieces must be empty
|| st->materialKey != si.materialKey
|| st->npMaterial[WHITE] != si.npMaterial[WHITE]
|| st->npMaterial[BLACK] != si.npMaterial[BLACK]
- || st->psq != si.psq)
+ || st->psq != si.psq
+ || st->checkersBB != si.checkersBB)
return false;
}
- if ((*step)++, testCheckerCount && popcount<Full>(st->checkersBB) > 2)
- return false;
+ if ((*step)++, testKingCount)
+ if ( std::count(board, board + SQUARE_NB, W_KING) != 1
+ || std::count(board, board + SQUARE_NB, B_KING) != 1)
+ return false;
+
+ if ((*step)++, testKingCapture)
+ if (attackers_to(king_square(~sideToMove)) & pieces(sideToMove))
+ return false;
if ((*step)++, testPieceCounts)
for (Color c = WHITE; c <= BLACK; ++c)