Fix (a lot but maybe not all of) Chakart
[xogo.git] / base_rules.js
index 864bb33..8ad0894 100644 (file)
@@ -87,6 +87,10 @@ export default class ChessRules {
       (!!this.options["recycle"] && !this.options["teleport"])
     );
   }
+  // Some variants do not store reserve state (Align4, Chakart...)
+  get hasReserveFen() {
+    return this.hasReserve;
+  }
 
   get noAnimate() {
     return !!this.options["dark"];
@@ -282,7 +286,7 @@ export default class ChessRules {
       parts.push(`"flags":"${this.getFlagsFen()}"`);
     if (this.hasEnpassant)
       parts.push(`"enpassant":"${this.getEnpassantFen()}"`);
-    if (this.hasReserve)
+    if (this.hasReserveFen)
       parts.push(`"reserve":"${this.getReserveFen()}"`);
     if (this.options["crazyhouse"])
       parts.push(`"ispawn":"${this.getIspawnFen()}"`);
@@ -530,6 +534,22 @@ export default class ChessRules {
     return `${this.containerId}|rnum-${color}${piece}`;
   }
 
+  static AddClass_es(piece, class_es) {
+    if (!Array.isArray(class_es))
+      class_es = [class_es];
+    class_es.forEach(cl => {
+      piece.classList.add(cl);
+    });
+  }
+
+  static RemoveClass_es(piece, class_es) {
+    if (!Array.isArray(class_es))
+      class_es = [class_es];
+    class_es.forEach(cl => {
+      piece.classList.remove(cl);
+    });
+  }
+
   graphicalInit() {
     // NOTE: not window.onresize = this.re_drawBoardElts because scope (this)
     window.onresize = () => this.re_drawBoardElements();
@@ -645,7 +665,7 @@ export default class ChessRules {
           const color = this.getColor(i, j);
           const piece = this.getPiece(i, j);
           this.g_pieces[i][j] = document.createElement("piece");
-          this.g_pieces[i][j].classList.add(this.pieces()[piece]["class"]);
+          C.AddClass_es(this.g_pieces[i][j], this.pieces()[piece]["class"]);
           this.g_pieces[i][j].classList.add(C.GetColorClass(color));
           this.g_pieces[i][j].style.width = pieceWidth + "px";
           this.g_pieces[i][j].style.height = pieceWidth + "px";
@@ -663,24 +683,17 @@ export default class ChessRules {
       this.re_drawReserve(['w', 'b'], r);
   }
 
-  // NOTE: assume !!this.reserve
+  // NOTE: assume this.reserve != null
   re_drawReserve(colors, r) {
     if (this.r_pieces) {
       // Remove (old) reserve pieces
       for (let c of colors) {
-        if (!this.reserve[c])
-          continue;
-        Object.keys(this.reserve[c]).forEach(p => {
-          if (this.r_pieces[c][p]) {
-            this.r_pieces[c][p].remove();
-            delete this.r_pieces[c][p];
-            const numId = this.getReserveNumId(c, p);
-            document.getElementById(numId).remove();
-          }
+        Object.keys(this.r_pieces[c]).forEach(p => {
+          this.r_pieces[c][p].remove();
+          delete this.r_pieces[c][p];
+          const numId = this.getReserveNumId(c, p);
+          document.getElementById(numId).remove();
         });
-        let reservesDiv = document.getElementById("reserves_" + c);
-        if (reservesDiv)
-          reservesDiv.remove();
       }
     }
     else
@@ -689,6 +702,9 @@ export default class ChessRules {
     if (!r)
       r = container.querySelector(".chessboard").getBoundingClientRect();
     for (let c of colors) {
+      let reservesDiv = document.getElementById("reserves_" + c);
+      if (reservesDiv)
+        reservesDiv.remove();
       if (!this.reserve[c])
         continue;
       const nbR = this.getNbReservePieces(c);
@@ -717,8 +733,7 @@ export default class ChessRules {
         r_cell.style.height = sqResSize + "px";
         rcontainer.appendChild(r_cell);
         let piece = document.createElement("piece");
-        const pieceSpec = this.pieces()[p];
-        piece.classList.add(pieceSpec["class"]);
+        C.AddClass_es(piece, this.pieces()[p]["class"]);
         piece.classList.add(C.GetColorClass(c));
         piece.style.width = "100%";
         piece.style.height = "100%";
@@ -1017,8 +1032,8 @@ export default class ChessRules {
       choice.style.backgroundColor = "lightyellow";
       choice.onclick = () => callback(moves[i]);
       const piece = document.createElement("piece");
-      const pieceSpec = this.pieces()[moves[i].appear[0].p];
-      piece.classList.add(pieceSpec["class"]);
+      const cdisp = moves[i].choice || moves[i].appear[0].p;
+      C.AddClass_es(piece, this.pieces()[cdisp]["class"]);
       piece.classList.add(C.GetColorClass(color));
       piece.style.width = "100%";
       piece.style.height = "100%";
@@ -1050,7 +1065,7 @@ export default class ChessRules {
       return "white";
     if (c == 'b')
       return "black";
-    return ""; //unidentified color
+    return "other-color"; //unidentified color
   }
 
   // Assume square i,j isn't empty
@@ -1485,6 +1500,11 @@ export default class ChessRules {
     return false;
   }
 
+  canStepOver(i, j) {
+    // In some variants, objects on boards don't stop movement (Chakart)
+    return this.board[i][j] == "";
+  }
+
   // Generic method to find possible moves of "sliding or jumping" pieces
   getPotentialMovesOf(piece, [x, y]) {
     const color = this.getColor(x, y);
@@ -1513,7 +1533,7 @@ export default class ChessRules {
           let stepCounter = 0;
           while (
             this.onBoard(i, j) &&
-            (this.board[i][j] == "" || (i == x && j == y))
+            (this.canStepOver(i, j) || (i == x && j == y))
           ) {
             if (
               type != "attack" &&
@@ -2164,7 +2184,7 @@ export default class ChessRules {
     const pieceWidth = this.getPieceWidth(r.width);
     move.appear.forEach(a => {
       this.g_pieces[a.x][a.y] = document.createElement("piece");
-      this.g_pieces[a.x][a.y].classList.add(this.pieces()[a.p]["class"]);
+      C.AddClass_es(this.g_pieces[a.x][a.y], this.pieces()[a.p]["class"]);
       this.g_pieces[a.x][a.y].classList.add(C.GetColorClass(a.c));
       this.g_pieces[a.x][a.y].style.width = pieceWidth + "px";
       this.g_pieces[a.x][a.y].style.height = pieceWidth + "px";
@@ -2217,8 +2237,8 @@ export default class ChessRules {
     const pieces = this.pieces();
     if (move.drag) {
       const startCode = this.getPiece(move.start.x, move.start.y);
-      movingPiece.classList.remove(pieces[startCode]["class"]);
-      movingPiece.classList.add(pieces[move.drag.p]["class"]);
+      C.RemoveClass_es(movingPiece, pieces[startCode]["class"]);
+      C.AddClass_es(movingPiece, pieces[move.drag.p]["class"]);
       const apparentColor = this.getColor(move.start.x, move.start.y);
       if (apparentColor != move.drag.c) {
         movingPiece.classList.remove(C.GetColorClass(apparentColor));