From 6e37b8c3a42e2306a88ae0ea2609dfaa6a21ca3f Mon Sep 17 00:00:00 2001 From: RainRat Date: Thu, 7 Sep 2023 11:50:32 -0700 Subject: [PATCH] Opposite castling (#710) --- src/parser.cpp | 1 + src/position.cpp | 7 +++++++ src/variant.h | 1 + src/variants.ini | 4 ++++ 4 files changed, 13 insertions(+), 0 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 4b07440..47fd5d2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -388,6 +388,7 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("castlingRookPieces", v->castlingRookPieces[BLACK], v->pieceToChar); parse_attribute("castlingRookPiecesWhite", v->castlingRookPieces[WHITE], v->pieceToChar); parse_attribute("castlingRookPiecesBlack", v->castlingRookPieces[BLACK], v->pieceToChar); + parse_attribute("oppositeCastling", v->oppositeCastling); parse_attribute("checking", v->checking); parse_attribute("dropChecks", v->dropChecks); parse_attribute("mustCapture", v->mustCapture); diff --git a/src/position.cpp b/src/position.cpp index a87ce1d..5d50488 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1659,6 +1659,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { { k ^= Zobrist::castling[st->castlingRights]; st->castlingRights &= ~(castlingRightsMask[from] | castlingRightsMask[to]); + + // Remove castling rights from opponent on the same side if oppositeCastling + if ((var->oppositeCastling) && (type_of(m) == CASTLING)) + { + bool kingSide = to > from; + st->castlingRights &= ~(~us & (kingSide ? KING_SIDE : QUEEN_SIDE)); + } k ^= Zobrist::castling[st->castlingRights]; } diff --git a/src/variant.h b/src/variant.h index 37de420..94f67b3 100644 --- a/src/variant.h +++ b/src/variant.h @@ -83,6 +83,7 @@ struct Variant { File castlingRookKingsideFile = FILE_MAX; // only has to match if rook is not in corner in non-960 variants File castlingRookQueensideFile = FILE_A; // only has to match if rook is not in corner in non-960 variants PieceSet castlingRookPieces[COLOR_NB] = {piece_set(ROOK), piece_set(ROOK)}; + bool oppositeCastling = false; PieceType kingType = KING; bool checking = true; bool dropChecks = true; diff --git a/src/variants.ini b/src/variants.ini index 71cb8d2..45327f5 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -189,6 +189,7 @@ # castlingRookKingsideFile: starting file of castlingRookPieces on kingside (if not in corner) [File] (default: l) # castlingRookQueensideFile: starting file of castlingRookPieces on queenside (if not in corner) [File] (default: a) # castlingRookPieces: second piece type that participates in castling [PieceSet] (default: r) +# oppositeCastling: can't castle same side as opponent [bool] (default: false) # checking: allow checks [bool] (default: true) # dropChecks: allow checks by piece drops [bool] (default: true) # mustCapture: captures are mandatory (check evasion still takes precedence) [bool] (default: false) @@ -1672,3 +1673,6 @@ enclosingDrop = none maxRank = 7 maxFile = 7 startFen = 1PPPPP1/p5P/p5P/p5P/p5P/p5P/1ppppp1 + +[opposite-castling:chess] +oppositeCastling = true -- 1.7.0.4