Fix king tracking bugs in Pacosako + Otage
[vchess.git] / client / src / variants / Pacosako.js
index b67d429..cde5039 100644 (file)
@@ -43,7 +43,7 @@ export class PacosakoRules extends ChessRules {
     if (position.length == 0) return false;
     const rows = position.split("/");
     if (rows.length != V.size.x) return false;
-    let kingSymb = ['k', 'g', 'm', 'u', 'x', '_'];
+    let kingSymb = ['k', 'g', 'm', 'u', 'x', 'z', '_'];
     let kings = { 'k': 0, 'K': 0 };
     for (let row of rows) {
       let sumElts = 0;
@@ -104,7 +104,7 @@ export class PacosakoRules extends ChessRules {
     this.kingPos = { w: [-1, -1], b: [-1, -1] };
     const fenRows = V.ParseFen(fen).position.split("/");
     const startRow = { 'w': V.size.x - 1, 'b': 0 };
-    const kingSymb = ['k', 'g', 'm', 'u', 'x', '_'];
+    const kingSymb = ['k', 'g', 'm', 'u', 'x', 'z', '_'];
     for (let i = 0; i < fenRows.length; i++) {
       let k = 0;
       for (let j = 0; j < fenRows[i].length; j++) {
@@ -600,10 +600,23 @@ export class PacosakoRules extends ChessRules {
     // "positions" = array of FENs to detect infinite loops. Example:
     // r1q1k2r/p1Pb1ppp/5n2/1f1p4/AV5P/P1eDP3/3B1PP1/R3K1NR,
     // Bxd2 Bxc3 Bxb4 Bxc3 Bxb4 etc.
-    const newPos = { fen: super.getBaseFen(), piece: released };
-    if (positions.some(p => p.piece == newPos.piece && p.fen == newPos.fen))
+    const newPos = {
+      fen: super.getBaseFen(),
+      piece: released,
+      from: fromSquare
+    };
+    if (
+      positions.some(p => {
+        return (
+          p.piece == newPos.piece &&
+          p.fen == newPos.fen &&
+          p.from == newPos.from
+        );
+      })
+    ) {
       // Start of an infinite loop: exit
       return false;
+    }
     positions.push(newPos);
     const rank = (color == 'w' ? 0 : 7);
     const moves = this.getPotentialMovesFrom(fromSquare);
@@ -726,14 +739,23 @@ export class PacosakoRules extends ChessRules {
     const c = this.turn;
     const L = this.lastMoveEnd.length;
     const lm = this.lastMoveEnd[L-1];
-    const piece = (!!lm ? lm.p : move.vanish[0].p);
+    // NOTE: lm.p != V.KING, always.
+    const piece =
+      !!lm
+        ? lm.p :
+        this.getPiece(move.vanish[0].x, move.vanish[0].y);
     if (piece == V.KING)
       this.kingPos[c] = [move.appear[0].x, move.appear[0].y];
     this.updateCastleFlags(move, piece);
     const pawnFirstRank = (c == 'w' ? 6 : 1);
-    if (move.start.x == pawnFirstRank)
-      // This move (potentially) turns off a 2-squares pawn flag
+    if (
+      move.start.x == pawnFirstRank &&
+      piece == V.PAWN &&
+      Math.abs(move.end.x - move.start.x) == 2
+    ) {
+      // This move turns off a 2-squares pawn flag
       this.pawnFlags[c][move.start.y] = false;
+    }
   }
 
   play(move) {