Some more debug on Checkered (still not ready: turn/color issues..)
[xogo.git] / variants / Checkered / class.js
index 9c78243..e0872f6 100644 (file)
@@ -28,7 +28,13 @@ export default class CheckeredRules extends ChessRules {
     };
   }
 
-  static board2fen(b) {
+  static GetColorClass(c) {
+    if (c == 'c')
+      return "checkered";
+    return C.GetColorClass(c);
+  }
+
+  board2fen(b) {
     const checkered_codes = {
       p: "s",
       q: "t",
@@ -41,7 +47,7 @@ export default class CheckeredRules extends ChessRules {
     return super.board2fen(b);
   }
 
-  static fen2board(f) {
+  fen2board(f) {
     // Tolerate upper-case versions of checkered pieces (why not?)
     const checkered_pieces = {
       s: "p",
@@ -60,6 +66,12 @@ export default class CheckeredRules extends ChessRules {
     return super.fen2board(f);
   }
 
+  genRandInitBaseFen() {
+    let res = super.genRandInitBaseFen();
+    res.o.flags += "1".repeat(16); //pawns flags
+    return res;
+  }
+
   getPartFen(o) {
     return Object.assign(
       {
@@ -107,24 +119,33 @@ export default class CheckeredRules extends ChessRules {
 
   pieces(color, x, y) {
     let baseRes = super.pieces(color, x, y);
-    if (
-      this.getPiece(x, y) == 'p' &&
-      this.stage == 2 &&
-      this.getColor(x, y) == 'c'
-    ) {
+    if (this.getPiece(x, y) == 'p' && color == 'c') {
+      const pawnShift = this.getPawnShift(this.turn); //cannot trust color
+      const initRank = (
+        (this.stage == 2 && [1, 6].includes(x)) ||
+        (this.stage == 1 &&
+          ((x == 1 && this.turn == 'b') || (x == 6 && this.turn == 'w'))
+        )
+      );
       // Checkered pawns on stage 2 are bidirectional
-      const initRank = ((color == 'w' && x >= 6) || (color == 'b' && x <= 1));
+      let moveSteps = [[pawnShift, 0]],
+          attackSteps = [[pawnShift, 1], [pawnShift, -1]];
+      if (this.stage == 2) {
+        moveSteps.push([-pawnShift, 0]);
+        Array.prototype.push.apply(attackSteps,
+          [[-pawnShift, 1], [-pawnShift, -1]]);
+      }
       baseRes['p'] = {
         "class": "pawn",
         moves: [
           {
-            steps: [[1, 0], [-1, 0]],
+            steps: moveSteps,
             range: (initRank ? 2 : 1)
           }
         ],
         attack: [
           {
-            steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]],
+            steps: attackSteps,
             range: 1
           }
         ]
@@ -243,7 +264,7 @@ export default class CheckeredRules extends ChessRules {
             return false; //forbidden 2-squares jumps
           }
           if (
-            this.board[m.end.x][m.end.y] == V.EMPTY &&
+            this.board[m.end.x][m.end.y] == "" &&
             m.vanish.length == 2 &&
             this.getColor(m.start.x, m.start.y) == "c"
           ) {
@@ -304,7 +325,7 @@ export default class CheckeredRules extends ChessRules {
 
   filterValid(moves) {
     const color = this.turn;
-    if (stage == 2 && this.sideCheckered == color)
+    if (this.stage == 2 && this.sideCheckered == color)
       // Checkered cannot be under check (no king)
       return moves;
     let kingPos = super.searchKingPos(color);
@@ -312,16 +333,25 @@ export default class CheckeredRules extends ChessRules {
       // Must consider both kings (attacked by checkered side)
       kingPos = [kingPos, super.searchKingPos(C.GetOppTurn(this.turn))];
     const oppCols = this.getOppCols(color);
-    return moves.filter(m => {
+    // Artificial turn change required, because canTake uses turn info.
+    // canTake is called from underCheck --> ... --> findDestSquares
+    this.turn = C.GetOppTurn(this.turn);
+    const filteredMoves = moves.filter(m => {
       this.playOnBoard(m);
+      if (m.vanish[0].p == 'k')
+        kingPos[0] = [m.appear[0].x, m.appear[0].y];
       let res = true;
-      if (stage == 1)
+      if (this.stage == 1)
         res = !this.oppositeMoves(this.cmove, m);
       if (res && m.appear.length > 0)
         res = !this.underCheck(kingPos, oppCols);
+      if (m.vanish[0].p == 'k')
+        kingPos[0] = [m.vanish[0].x, m.vanish[0].y];
       this.undoOnBoard(m);
       return res;
     });
+    this.turn = C.GetOppTurn(this.turn);
+    return filteredMoves;
   }
 
   atLeastOneMove(color) {
@@ -353,7 +383,7 @@ export default class CheckeredRules extends ChessRules {
   underCheck(square_s, oppCols) {
     if (this.stage == 2 && oppCol != this.sideCheckered)
       return false; //checkered pieces is me, I'm not under check
-    return super.underAttack(square_s, oppCols);
+    return square_s.some(sq => super.underAttack(sq, oppCols));
   }
 
   prePlay(move) {
@@ -361,7 +391,7 @@ export default class CheckeredRules extends ChessRules {
       super.prePlay(move);
       if (
         [1, 6].includes(move.start.x) &&
-        move.vanish[0].p == V.PAWN &&
+        move.vanish[0].p == 'p' &&
         Math.abs(move.end.x - move.start.x) == 2
       ) {
         // This move turns off a 2-squares pawn flag