ss >> st->rule50 >> fullMoves;
// Various initialisations
- castleRightsMask[make_square(initialKFile, RANK_1)] ^= WHITE_OO | WHITE_OOO;
- castleRightsMask[make_square(initialKFile, RANK_8)] ^= BLACK_OO | BLACK_OOO;
- castleRightsMask[make_square(initialKRFile, RANK_1)] ^= WHITE_OO;
- castleRightsMask[make_square(initialKRFile, RANK_8)] ^= BLACK_OO;
- castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO;
- castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO;
-
chess960 = isChess960;
find_checkers();
}
+/// Position::set_castle() is an helper function used to set
+/// correct castling related flags.
+
+void Position::set_castle(int f, Square ksq, Square rsq) {
+
+ st->castleRights |= f;
+ castleRightsMask[ksq] ^= f;
+ castleRightsMask[rsq] ^= f;
+ castleRookSquare[f] = rsq;
+}
+
+
/// Position::set_castling_rights() sets castling parameters castling avaiability.
/// This function is compatible with 3 standards: Normal FEN standard, Shredder-FEN
/// that uses the letters of the columns on which the rooks began the game instead
Square sqA = relative_square(c, SQ_A1);
Square sqH = relative_square(c, SQ_H1);
- initialKFile = square_file(king_square(c));
+ Square rsq, ksq = king_square(c);
if (toupper(token) == 'K')
{
- for (Square sq = sqH; sq >= sqA; sq--)
- if (piece_on(sq) == make_piece(c, ROOK))
- {
- set_castle_kingside(c);
- initialKRFile = square_file(sq);
- break;
- }
+ for (rsq = sqH; piece_on(rsq) != make_piece(c, ROOK); rsq--) {}
+ set_castle(WHITE_OO << c, ksq, rsq);
}
else if (toupper(token) == 'Q')
{
- for (Square sq = sqA; sq <= sqH; sq++)
- if (piece_on(sq) == make_piece(c, ROOK))
- {
- set_castle_queenside(c);
- initialQRFile = square_file(sq);
- break;
- }
+ for (rsq = sqA; piece_on(rsq) != make_piece(c, ROOK); rsq++) {}
+ set_castle(WHITE_OOO << c, ksq, rsq);
}
else if (toupper(token) >= 'A' && toupper(token) <= 'H')
{
- File rookFile = File(toupper(token) - 'A');
+ Square rsq = make_square(File(toupper(token) - 'A'), RANK_1);
- if (rookFile < initialKFile)
- {
- set_castle_queenside(c);
- initialQRFile = rookFile;
- }
+ if (square_file(rsq) < square_file(ksq))
+ set_castle(WHITE_OOO << c, ksq, rsq);
else
- {
- set_castle_kingside(c);
- initialKRFile = rookFile;
- }
+ set_castle(WHITE_OO << c, ksq, rsq);
}
}
if (st->castleRights != CASTLES_NONE)
{
- if (can_castle_kingside(WHITE))
- fen += chess960 ? char(toupper(file_to_char(initialKRFile))) : 'K';
+ if (can_castle(WHITE_OO))
+ fen += chess960 ? char(toupper(file_to_char(square_file(castle_rook_square(WHITE_OO))))) : 'K';
- if (can_castle_queenside(WHITE))
- fen += chess960 ? char(toupper(file_to_char(initialQRFile))) : 'Q';
+ if (can_castle(WHITE_OOO))
+ fen += chess960 ? char(toupper(file_to_char(square_file(castle_rook_square(WHITE_OOO))))) : 'Q';
- if (can_castle_kingside(BLACK))
- fen += chess960 ? file_to_char(initialKRFile) : 'k';
+ if (can_castle(BLACK_OO))
+ fen += chess960 ? file_to_char(square_file(castle_rook_square(BLACK_OO))) : 'k';
- if (can_castle_queenside(BLACK))
- fen += chess960 ? file_to_char(initialQRFile) : 'q';
+ if (can_castle(BLACK_OOO))
+ fen += chess960 ? file_to_char(square_file(castle_rook_square(BLACK_OOO))) : 'q';
} else
fen += '-';
castleRightsMask[sq] = ALL_CASTLES;
sideToMove = WHITE;
- initialKFile = FILE_E;
- initialKRFile = FILE_H;
- initialQRFile = FILE_A;
}
sideToMove = opposite_color(pos.side_to_move());
// Castling rights
- if (pos.can_castle_kingside(WHITE)) set_castle_kingside(BLACK);
- if (pos.can_castle_queenside(WHITE)) set_castle_queenside(BLACK);
- if (pos.can_castle_kingside(BLACK)) set_castle_kingside(WHITE);
- if (pos.can_castle_queenside(BLACK)) set_castle_queenside(WHITE);
-
- initialKFile = pos.initialKFile;
- initialKRFile = pos.initialKRFile;
- initialQRFile = pos.initialQRFile;
-
- castleRightsMask[make_square(initialKFile, RANK_1)] ^= (WHITE_OO | WHITE_OOO);
- castleRightsMask[make_square(initialKFile, RANK_8)] ^= (BLACK_OO | BLACK_OOO);
- castleRightsMask[make_square(initialKRFile, RANK_1)] ^= WHITE_OO;
- castleRightsMask[make_square(initialKRFile, RANK_8)] ^= BLACK_OO;
- castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO;
- castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO;
+ if (pos.can_castle(WHITE_OO))
+ set_castle(BLACK_OO, king_square(BLACK), flip_square(pos.castle_rook_square(WHITE_OO)));
+ if (pos.can_castle(WHITE_OOO))
+ set_castle(BLACK_OOO, king_square(BLACK), flip_square(pos.castle_rook_square(WHITE_OOO)));
+ if (pos.can_castle(BLACK_OO))
+ set_castle(WHITE_OO, king_square(WHITE), flip_square(pos.castle_rook_square(BLACK_OO)));
+ if (pos.can_castle(BLACK_OOO))
+ set_castle(WHITE_OOO, king_square(WHITE), flip_square(pos.castle_rook_square(BLACK_OOO)));
// En passant square
if (pos.st->epSquare != SQ_NONE)
if (piece_on(king_square(BLACK)) != BK)
return false;
- // Castle files OK?
- if (failedStep) (*failedStep)++;
- if (!square_is_ok(make_square(initialKRFile, RANK_1)))
- return false;
-
- if (!square_is_ok(make_square(initialQRFile, RANK_1)))
- return false;
-
// Do both sides have exactly one king?
if (failedStep) (*failedStep)++;
if (debugKingCount)
if (failedStep) (*failedStep)++;
if (debugCastleSquares)
- {
- for (Color c = WHITE; c <= BLACK; c++)
+ for (CastleRight f = WHITE_OO; f <= BLACK_OOO; f = CastleRight(f << 1))
{
- if (can_castle_kingside(c) && piece_on(initial_kr_square(c)) != make_piece(c, ROOK))
- return false;
+ if (!can_castle(f))
+ continue;
- if (can_castle_queenside(c) && piece_on(initial_qr_square(c)) != make_piece(c, ROOK))
+ Piece rook = (f & (WHITE_OO | WHITE_OOO) ? WR : BR);
+
+ if ( castleRightsMask[castleRookSquare[f]] != (ALL_CASTLES ^ f)
+ || piece_on(castleRookSquare[f]) != rook)
return false;
}
- if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
- return false;
- if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
- return false;
- if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
- return false;
- if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
- return false;
- }
if (failedStep) *failedStep = 0;
return true;
/// Castle rights, encoded as bit fields
-enum CastleRights {
+enum CastleRight {
CASTLES_NONE = 0,
WHITE_OO = 1,
BLACK_OO = 2,
Square king_square(Color c) const;
// Castling rights
- bool can_castle_kingside(Color c) const;
- bool can_castle_queenside(Color c) const;
+ bool can_castle(CastleRight f) const;
bool can_castle(Color c) const;
- Square initial_kr_square(Color c) const;
- Square initial_qr_square(Color c) const;
+ Square castle_rook_square(CastleRight f) const;
// Bitboards for pinned pieces and discovered check candidates
Bitboard discovered_check_candidates(Color c) const;
void clear();
void detach();
void put_piece(Piece p, Square s);
- void set_castle_kingside(Color c);
- void set_castle_queenside(Color c);
+ void set_castle(int f, Square ksq, Square rsq);
void set_castling_rights(char token);
bool move_is_pl_slow(const Move m) const;
Color sideToMove;
Key history[MaxGameLength];
int castleRightsMask[64];
+ Square castleRookSquare[16]; // [CastleRights]
StateInfo startState;
- File initialKFile, initialKRFile, initialQRFile;
bool chess960;
int fullMoves;
int threadID;
return pieceList[c][KING][0];
}
-inline bool Position::can_castle_kingside(Color c) const {
- return st->castleRights & (WHITE_OO << c);
-}
-
-inline bool Position::can_castle_queenside(Color c) const {
- return st->castleRights & (WHITE_OOO << c);
+inline bool Position::can_castle(CastleRight f) const {
+ return st->castleRights & f;
}
inline bool Position::can_castle(Color c) const {
return st->castleRights & ((WHITE_OO | WHITE_OOO) << c);
}
-inline void Position::set_castle_kingside(Color c) {
- st->castleRights |= (WHITE_OO << c);
-}
-
-inline void Position::set_castle_queenside(Color c) {
- st->castleRights |= (WHITE_OOO << c);
-}
-
-inline Square Position::initial_kr_square(Color c) const {
- return relative_square(c, make_square(initialKRFile, RANK_1));
-}
-
-inline Square Position::initial_qr_square(Color c) const {
- return relative_square(c, make_square(initialQRFile, RANK_1));
+inline Square Position::castle_rook_square(CastleRight f) const {
+ return castleRookSquare[f];
}
template<>