Fix Benedict rules
[vchess.git] / client / src / base_rules.js
index 056f477..5bf47f7 100644 (file)
@@ -4,8 +4,8 @@
 import { ArrayFun } from "@/utils/array";
 import { randInt, shuffle } from "@/utils/alea";
 
+// class "PiPo": Piece + Position
 export const PiPo = class PiPo {
-  //Piece+Position
   // o: {piece[p], color[c], posX[x], posY[y]}
   constructor(o) {
     this.p = o.p;
@@ -15,7 +15,6 @@ export const PiPo = class PiPo {
   }
 };
 
-// TODO: for animation, moves should contains "moving" and "fading" maybe...
 export const Move = class Move {
   // o: {appear, vanish, [start,] [end,]}
   // appear,vanish = arrays of PiPo
@@ -33,13 +32,26 @@ export const ChessRules = class ChessRules {
   //////////////
   // MISC UTILS
 
+  // Some variants don't have flags:
   static get HasFlags() {
     return true;
-  } //some variants don't have flags
+  }
 
+  // Some variants don't have en-passant
   static get HasEnpassant() {
     return true;
-  } //some variants don't have ep.
+  }
+
+  // Some variants cannot have analyse mode
+  static get CanAnalyze() {
+    return true;
+  }
+
+  // Some variants show incomplete information,
+  // and thus show only a partial moves list or no list at all.
+  static get ShowMoves() {
+    return "all";
+  }
 
   // Path to pieces
   static getPpath(b) {
@@ -84,9 +96,12 @@ export const ChessRules = class ChessRules {
     if (position.length == 0) return false;
     const rows = position.split("/");
     if (rows.length != V.size.x) return false;
+    let kings = {};
     for (let row of rows) {
       let sumElts = 0;
       for (let i = 0; i < row.length; i++) {
+        if (['K','k'].includes(row[i]))
+          kings[row[i]] = true;
         if (V.PIECES.includes(row[i].toLowerCase())) sumElts++;
         else {
           const num = parseInt(row[i]);
@@ -96,6 +111,9 @@ export const ChessRules = class ChessRules {
       }
       if (sumElts != V.size.y) return false;
     }
+    // Both kings should be on board:
+    if (Object.keys(kings).length != 2)
+      return false;
     return true;
   }
 
@@ -417,7 +435,7 @@ export const ChessRules = class ChessRules {
     if (V.HasEnpassant) {
       const epSq =
         parsedFen.enpassant != "-"
-          ? V.SquareToCoords(parsedFen.enpassant)
+          ? this.getEpSquare(parsedFen.enpassant)
           : undefined;
       this.epSquares = [epSq];
     }
@@ -704,10 +722,11 @@ export const ChessRules = class ChessRules {
     const oppCol = V.GetOppCol(c);
     let moves = [];
     let i = 0;
+    // King, then rook:
     const finalSquares = [
       [2, 3],
       [V.size.y - 2, V.size.y - 3]
-    ]; //king, then rook
+    ];
     castlingCheck: for (
       let castleSide = 0;
       castleSide < 2;
@@ -1004,9 +1023,9 @@ export const ChessRules = class ChessRules {
 
   play(move) {
     // DEBUG:
-    //    if (!this.states) this.states = [];
-    //    const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
-    //    this.states.push(stateFen);
+//    if (!this.states) this.states = [];
+//    const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
+//    this.states.push(stateFen);
 
     if (V.HasFlags) move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo)
     if (V.HasEnpassant) this.epSquares.push(this.getEpSquare(move));
@@ -1025,9 +1044,9 @@ export const ChessRules = class ChessRules {
     this.unupdateVariables(move);
 
     // DEBUG:
-    //    const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
-    //    if (stateFen != this.states[this.states.length-1]) debugger;
-    //    this.states.pop();
+//    const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
+//    if (stateFen != this.states[this.states.length-1]) debugger;
+//    this.states.pop();
   }
 
   ///////////////
@@ -1036,7 +1055,6 @@ export const ChessRules = class ChessRules {
   // What is the score ? (Interesting if game is over)
   getCurrentScore() {
     if (this.atLeastOneMove())
-      // game not over
       return "*";
 
     // Game over