Change castle flags. Eightpieces still not OK, but almost
[vchess.git] / client / src / variants / Checkered.js
index 5f9bf8f..0e089f3 100644 (file)
@@ -44,7 +44,7 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     super.setOtherVariables(fen);
     // Local stack of non-capturing checkered moves:
     this.cmoves = [];
-    const cmove = fen.split(" ")[5];
+    const cmove = V.ParseFen(fen).cmove;
     if (cmove == "-") this.cmoves.push(null);
     else {
       this.cmoves.push({
@@ -65,7 +65,7 @@ export const VariantRules = class CheckeredRules extends ChessRules {
 
   static IsGoodFlags(flags) {
     // 4 for castle + 16 for pawns
-    return !!flags.match(/^[01]{20,20}$/);
+    return !!flags.match(/^[a-z]{4,4}[01]{16,16}$/);
   }
 
   setFlags(fenflags) {
@@ -74,7 +74,7 @@ export const VariantRules = class CheckeredRules extends ChessRules {
       w: [...Array(8).fill(true)], //pawns can move 2 squares?
       b: [...Array(8).fill(true)]
     };
-    const flags = fenflags.substr(4); //skip first 4 digits, for castle
+    const flags = fenflags.substr(4); //skip first 4 letters, for castle
     for (let c of ["w", "b"]) {
       for (let i = 0; i < 8; i++)
         this.pawnFlags[c][i] = flags.charAt((c == "w" ? 0 : 8) + i) == "1";
@@ -90,6 +90,13 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     this.pawnFlags = flags[1];
   }
 
+  getEpSquare(moveOrSquare) {
+    if (typeof moveOrSquare !== "object" || moveOrSquare.appear[0].c != 'c')
+      return super.getEpSquare(moveOrSquare);
+    // Checkered move: no en-passant
+    return undefined;
+  }
+
   getCmove(move) {
     if (move.appear[0].c == "c" && move.vanish.length == 1)
       return { start: move.start, end: move.end };
@@ -149,6 +156,77 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     return moves;
   }
 
+  getPotentialPawnMoves([x, y]) {
+    const color = this.turn;
+    let moves = [];
+    const [sizeX, sizeY] = [V.size.x, V.size.y];
+    const shiftX = color == "w" ? -1 : 1;
+    const startRank = color == "w" ? sizeX - 2 : 1;
+    const lastRank = color == "w" ? 0 : sizeX - 1;
+    const pawnColor = this.getColor(x, y); //can be  checkered
+
+    const finalPieces =
+      x + shiftX == lastRank
+        ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
+        : [V.PAWN];
+    if (this.board[x + shiftX][y] == V.EMPTY) {
+      // One square forward
+      for (let piece of finalPieces) {
+        moves.push(
+          this.getBasicMove([x, y], [x + shiftX, y], {
+            c: pawnColor,
+            p: piece
+          })
+        );
+      }
+      if (
+        x == startRank &&
+        this.board[x + 2 * shiftX][y] == V.EMPTY
+      ) {
+        // Two squares jump
+        moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y]));
+      }
+    }
+    // Captures
+    for (let shiftY of [-1, 1]) {
+      if (
+        y + shiftY >= 0 &&
+        y + shiftY < sizeY &&
+        this.board[x + shiftX][y + shiftY] != V.EMPTY &&
+        this.canTake([x, y], [x + shiftX, y + shiftY])
+      ) {
+        for (let piece of finalPieces) {
+          moves.push(
+            this.getBasicMove([x, y], [x + shiftX, y + shiftY], {
+              c: pawnColor,
+              p: piece
+            })
+          );
+        }
+      }
+    }
+
+    // En passant
+    const Lep = this.epSquares.length;
+    const epSquare = this.epSquares[Lep - 1]; //always at least one element
+    if (
+      !!epSquare &&
+      epSquare.x == x + shiftX &&
+      Math.abs(epSquare.y - y) == 1
+    ) {
+      let enpassantMove = this.getBasicMove([x, y], [epSquare.x, epSquare.y]);
+      enpassantMove.vanish.push({
+        x: x,
+        y: epSquare.y,
+        p: "p",
+        c: this.getColor(x, epSquare.y)
+      });
+      moves.push(enpassantMove);
+    }
+
+    return moves;
+  }
+
   canIplay(side, [x, y]) {
     return side == this.turn && [side, "c"].includes(this.getColor(x, y));
   }
@@ -201,7 +279,7 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     const oppCol = V.GetOppCol(this.turn);
     for (let i = 0; i < V.size.x; i++) {
       for (let j = 0; j < V.size.y; j++) {
-        // NOTE: just testing == color isn't enough because of checkred pieces
+        // NOTE: just testing == color isn't enough because of checkered pieces
         if (this.board[i][j] != V.EMPTY && this.getColor(i, j) != oppCol) {
           const moves = this.getPotentialMovesFrom([i, j]);
           if (moves.length > 0) {
@@ -253,12 +331,17 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     return res;
   }
 
-  updateVariables(move) {
-    super.updateVariables(move);
+  postPlay(move) {
+    super.postPlay(move);
     // Does this move turn off a 2-squares pawn flag?
-    const secondRank = [1, 6];
-    if (secondRank.includes(move.start.x) && move.vanish[0].p == V.PAWN)
+    if ([1, 6].includes(move.start.x) && move.vanish[0].p == V.PAWN)
       this.pawnFlags[move.start.x == 6 ? "w" : "b"][move.start.y] = false;
+    this.cmoves.push(this.getCmove(move));
+  }
+
+  postUndo(move) {
+    super.postUndo(move);
+    this.cmoves.pop();
   }
 
   getCurrentScore() {
@@ -296,9 +379,9 @@ export const VariantRules = class CheckeredRules extends ChessRules {
   }
 
   static GenRandInitFen(randomness) {
+    // Add 16 pawns flags + empty cmove:
     return ChessRules.GenRandInitFen(randomness)
-      // Add 16 pawns flags + empty cmove:
-      .replace(" w 0 1111", " w 0 11111111111111111111 -");
+      .slice(0, -2) + "1111111111111111 - -";
   }
 
   static ParseFen(fen) {
@@ -325,15 +408,8 @@ export const VariantRules = class CheckeredRules extends ChessRules {
     return fen;
   }
 
-  // TODO (design): this cmove update here or in (un)updateVariables ?
-  play(move) {
-    this.cmoves.push(this.getCmove(move));
-    super.play(move);
-  }
-
-  undo(move) {
-    this.cmoves.pop();
-    super.undo(move);
+  static get SEARCH_DEPTH() {
+    return 2;
   }
 
   getNotation(move) {