Paco-Sako: allow castling with a rook in union + fix a bug in isAttacked()
[vchess.git] / client / src / variants / Pacosako.js
index 5eb96b6..8cec688 100644 (file)
@@ -508,6 +508,8 @@ export class PacosakoRules extends ChessRules {
     castlingCheck: for (let castleSide = 0; castleSide < 2; castleSide++) {
       if (this.castleFlags[c][castleSide] >= 8) continue;
       const rookPos = this.castleFlags[c][castleSide];
+      const castlingColor = this.board[x][rookPos].charAt(0);
+      const castlingPiece = this.board[x][rookPos].charAt(1);
 
       // Nothing on the path of the king ?
       const finDist = finalSquares[castleSide][0] - y;
@@ -561,14 +563,14 @@ export class PacosakoRules extends ChessRules {
             new PiPo({
               x: x,
               y: finalSquares[castleSide][1],
-              p: V.ROOK,
-              c: c
+              p: castlingPiece,
+              c: castlingColor
             })
           ],
           vanish: [
             // King might be initially disguised (Titan...)
             new PiPo({ x: x, y: y, p: V.KING, c: c }),
-            new PiPo({ x: x, y: rookPos, p: V.ROOK, c: c })
+            new PiPo({ x: x, y: rookPos, p: castlingPiece, c: castlingColor })
           ],
           end:
             Math.abs(y - rookPos) <= 2
@@ -581,6 +583,14 @@ export class PacosakoRules extends ChessRules {
     return moves;
   }
 
+  getEnpassantCaptures(sq, shiftX) {
+    // HACK: when artificially change turn, do not consider en-passant
+    const mcMod2 = this.movesCount % 2;
+    const c = this.turn;
+    if ((c == 'w' && mcMod2 == 1) || (c == 'b' && mcMod2 == 0)) return [];
+    return super.getEnpassantCaptures(sq, shiftX);
+  }
+
   isAttacked_aux(files, color, positions, fromSquare, released) {
     // "positions" = array of FENs to detect infinite loops. Example:
     // r1q1k2r/p1Pb1ppp/5n2/1f1p4/AV5P/P1eDP3/3B1PP1/R3K1NR,
@@ -677,6 +687,23 @@ export class PacosakoRules extends ChessRules {
     this.postPlay(move);
   }
 
+  updateCastleFlags(move, piece) {
+    const c = V.GetOppCol(this.turn);
+    const firstRank = (c == "w" ? 7 : 0);
+    const oppCol = this.turn;
+    const oppFirstRank = 7 - firstRank;
+    if (piece == V.KING && move.appear.length > 0)
+      this.castleFlags[c] = [V.size.y, V.size.y];
+    else if (
+      move.start.x == firstRank &&
+      this.castleFlags[c].includes(move.start.y)
+    ) {
+      const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1);
+      this.castleFlags[c][flagIdx] = V.size.y;
+    }
+    // No more checking: a rook in union can take part in castling.
+  }
+
   postPlay(move) {
     if (move.vanish.length == 0)
       // A released piece just moved. Cannot be the king.