Opposite castling (#710)
authorRainRat <rainrat78@yahoo.ca>
Thu, 7 Sep 2023 18:50:32 +0000 (11:50 -0700)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2023 18:50:32 +0000 (20:50 +0200)
src/parser.cpp
src/position.cpp
src/variant.h
src/variants.ini

index 4b07440..47fd5d2 100644 (file)
@@ -388,6 +388,7 @@ Variant* VariantParser<DoCheck>::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);
index a87ce1d..5d50488 100644 (file)
@@ -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];
   }
 
index 37de420..94f67b3 100644 (file)
@@ -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;
index 71cb8d2..45327f5 100644 (file)
 # 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