Add Tencubed and Omega variants + some fixes (updateCastleFlags()) + cleaner FEN...
[vchess.git] / client / src / variants / Cannibal.js
index 1508f67..f7a9514 100644 (file)
@@ -33,6 +33,34 @@ export class CannibalRules extends ChessRules {
     return (Object.keys(V.KING_DECODE).includes(b[1]) ? "Cannibal/" : "") + b;
   }
 
+  static IsGoodPosition(position) {
+    if (position.length == 0) return false;
+    const rows = position.split("/");
+    if (rows.length != V.size.x) return false;
+    let kings = { "w": 0, "b": 0 };
+    const allPiecesCodes = V.PIECES.concat(Object.keys(V.KING_DECODE));
+    const kingBlackCodes = Object.keys(V.KING_DECODE).concat(['k']);
+    const kingWhiteCodes =
+      Object.keys(V.KING_DECODE).map(k => k.toUpperCase()).concat(['K']);
+    for (let row of rows) {
+      let sumElts = 0;
+      for (let i = 0; i < row.length; i++) {
+        if (kingBlackCodes.includes(row[i])) kings['b']++;
+        else if (kingWhiteCodes.includes(row[i])) kings['w']++;
+        if (allPiecesCodes.includes(row[i].toLowerCase())) sumElts++;
+        else {
+          const num = parseInt(row[i]);
+          if (isNaN(num)) return false;
+          sumElts += num;
+        }
+      }
+      if (sumElts != V.size.y) return false;
+    }
+    // Both kings should be on board, only one of each color:
+    if (Object.values(kings).some(v => v != 1)) return false;
+    return true;
+  }
+
   // Kings may be disguised:
   setOtherVariables(fen) {
     super.setOtherVariables(fen);
@@ -166,7 +194,8 @@ export class CannibalRules extends ChessRules {
 
   getAllValidMoves() {
     const moves = super.getAllValidMoves();
-    if (moves.some(m => m.vanish.length == 2)) return V.KeepCaptures(moves);
+    if (moves.some(m => m.vanish.length == 2 && m.appear.length == 1))
+      return V.KeepCaptures(moves);
     return moves;
   }
 
@@ -178,9 +207,10 @@ export class CannibalRules extends ChessRules {
       this.kingPos[c][0] = move.appear[0].x;
       this.kingPos[c][1] = move.appear[0].y;
       this.castleFlags[c] = [V.size.y, V.size.y];
-      return;
     }
-    super.updateCastleFlags(move);
+    // Next call is still required because the king may eat an opponent's rook
+    // TODO: castleFlags will be turned off twice then.
+    super.updateCastleFlags(move, piece);
   }
 
   postUndo(move) {
@@ -202,7 +232,18 @@ export class CannibalRules extends ChessRules {
     };
   }
 
-  static get SEARCH_DEPTH() {
-    return 4;
+  getNotation(move) {
+    let notation = super.getNotation(move);
+    const lastRank = (move.appear[0].c == "w" ? 0 : 7);
+    if (
+      move.end.x != lastRank &&
+      this.getPiece(move.start.x, move.start.y) == V.PAWN &&
+      move.vanish.length == 2 &&
+      move.appear[0].p != V.PAWN
+    ) {
+      // Fix "promotion" (transform indicator) from base_rules notation
+      notation = notation.slice(0, -2);
+    }
+    return notation;
   }
 };