Add 'pacoplay mode' to Paco-Sako
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 25 Apr 2021 08:38:53 +0000 (10:38 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 25 Apr 2021 08:38:53 +0000 (10:38 +0200)
client/src/translations/en.js
client/src/translations/es.js
client/src/translations/fr.js
client/src/translations/rules/Pacosako/en.pug
client/src/translations/rules/Pacosako/es.pug
client/src/translations/rules/Pacosako/fr.pug
client/src/variants/Pacosako.js

index 81614cf..bdc915a 100644 (file)
@@ -119,6 +119,7 @@ export const translations = {
   Previous_p: "Previous",
   "Processing... Please wait": "Processing... Please wait",
   Problems: "Problems",
   Previous_p: "Previous",
   "Processing... Please wait": "Processing... Please wait",
   Problems: "Problems",
+  "pacoplay mode": "pacoplay mode",
   Random: "Random",
   Randomness: "Randomness",
   Refuse: "Refuse",
   Random: "Random",
   Randomness: "Randomness",
   Refuse: "Refuse",
index 4fc5470..ca6b46d 100644 (file)
@@ -119,6 +119,7 @@ export const translations = {
   Previous_n: "Anterior",
   "Processing... Please wait": "Procesando... por favor espere",
   Problems: "Problemas",
   Previous_n: "Anterior",
   "Processing... Please wait": "Procesando... por favor espere",
   Problems: "Problemas",
+  "pacoplay mode": "modo pacoplay",
   Random: "Aleatorio",
   Randomness: "Grado de azar",
   Refuse: "Rechazar",
   Random: "Aleatorio",
   Randomness: "Grado de azar",
   Refuse: "Rechazar",
index 1ee78ee..fbe49ce 100644 (file)
@@ -119,6 +119,7 @@ export const translations = {
   Previous_n: "Précédente",
   "Processing... Please wait": "Traitement en cours... Attendez SVP",
   Problems: "Problèmes",
   Previous_n: "Précédente",
   "Processing... Please wait": "Traitement en cours... Attendez SVP",
   Problems: "Problèmes",
+  "pacoplay mode": "mode pacoplay",
   Random: "Aléatoire",
   Randomness: "Degré d'aléa",
   Refuse: "Refuser",
   Random: "Aléatoire",
   Randomness: "Degré d'aléa",
   Refuse: "Refuser",
index 2a787e8..eea42c8 100644 (file)
@@ -85,6 +85,7 @@ h3 Non-official rules
 p.
   I added some small changes, globally to complicate defense.
   These are not in the official rules.
 p.
   I added some small changes, globally to complicate defense.
   These are not in the official rules.
+  To disable them, check the box "pacoplay mode".
 
 ul
   li.
 
 ul
   li.
index a3a6f55..a138778 100644 (file)
@@ -88,6 +88,7 @@ h3 Reglas no oficiales
 p.
     Hice algunas adiciones, en general para complicar la defensa.
     No forman parte de las reglas oficiales.
 p.
     Hice algunas adiciones, en general para complicar la defensa.
     No forman parte de las reglas oficiales.
+    Para desactivarlos, marque la casilla "modo pacoplay".
 
 ul
   li.
 
 ul
   li.
index d8a46aa..edc52ca 100644 (file)
@@ -88,6 +88,7 @@ h3 Règles non-officielles
 p.
   J'ai effectué quelques ajouts, globalement pour compliquer la défense.
   Ils ne font pas partie des règles officielles.
 p.
   J'ai effectué quelques ajouts, globalement pour compliquer la défense.
   Ils ne font pas partie des règles officielles.
+  Pour les désactiver, cochez la case "mode pacoplay".
 
 ul
   li.
 
 ul
   li.
index 0462d2d..ddf2fab 100644 (file)
@@ -3,6 +3,19 @@ import { randInt } from "@/utils/alea";
 
 export class PacosakoRules extends ChessRules {
 
 
 export class PacosakoRules extends ChessRules {
 
+  static get Options() {
+    return {
+      select: ChessRules.Options.select,
+      check: [
+        {
+          label: "pacoplay mode",
+          variable: "pacoplay",
+          defaut: false
+        }
+      ]
+    };
+  }
+
   static get IMAGE_EXTENSION() {
     return ".png";
   }
   static get IMAGE_EXTENSION() {
     return ".png";
   }
@@ -126,21 +139,24 @@ export class PacosakoRules extends ChessRules {
   }
 
   setOtherVariables(fen) {
   }
 
   setOtherVariables(fen) {
-    super.setOtherVariables(fen);
     // Stack of "last move" only for intermediate chaining
     this.lastMoveEnd = [null];
     // Local stack of non-capturing union moves:
     this.umoves = [];
     const umove = V.ParseFen(fen).umove;
     // Stack of "last move" only for intermediate chaining
     this.lastMoveEnd = [null];
     // Local stack of non-capturing union moves:
     this.umoves = [];
     const umove = V.ParseFen(fen).umove;
-    if (umove == "-") this.umoves.push(null);
-    else {
-      this.umoves.push({
-        start: ChessRules.SquareToCoords(umove.substr(0, 2)),
-        end: ChessRules.SquareToCoords(umove.substr(2))
-      });
+    this.pacoplay = !umove; //"pacoplay.com mode" ?
+    if (!this.pacoplay) {
+      if (umove == "-") this.umoves.push(null);
+      else {
+        this.umoves.push({
+          start: ChessRules.SquareToCoords(umove.substr(0, 2)),
+          end: ChessRules.SquareToCoords(umove.substr(2))
+        });
+      }
     }
     // Local stack of positions to avoid redundant moves:
     this.repetitions = [];
     }
     // Local stack of positions to avoid redundant moves:
     this.repetitions = [];
+    super.setOtherVariables(fen);
   }
 
   static IsGoodFen(fen) {
   }
 
   static IsGoodFen(fen) {
@@ -153,12 +169,13 @@ export class PacosakoRules extends ChessRules {
   }
 
   static IsGoodFlags(flags) {
   }
 
   static IsGoodFlags(flags) {
-    // 4 for castle + 16 for pawns
-    return !!flags.match(/^[a-z]{4,4}[01]{16,16}$/);
+    // 4 for castle + 16 for pawns (more permissive, for pacoplay mode)
+    return !!flags.match(/^[a-z]{4,4}[01]{0,16}$/);
   }
 
   setFlags(fenflags) {
     super.setFlags(fenflags); //castleFlags
   }
 
   setFlags(fenflags) {
     super.setFlags(fenflags); //castleFlags
+    if (this.pacoplay) return;
     this.pawnFlags = {
       w: [...Array(8)], //pawns can move 2 squares?
       b: [...Array(8)]
     this.pawnFlags = {
       w: [...Array(8)], //pawns can move 2 squares?
       b: [...Array(8)]
@@ -171,12 +188,16 @@ export class PacosakoRules extends ChessRules {
   }
 
   aggregateFlags() {
   }
 
   aggregateFlags() {
+    if (!this.pacoplay) return super.aggregateFlags();
     return [this.castleFlags, this.pawnFlags];
   }
 
   disaggregateFlags(flags) {
     return [this.castleFlags, this.pawnFlags];
   }
 
   disaggregateFlags(flags) {
-    this.castleFlags = flags[0];
-    this.pawnFlags = flags[1];
+    if (!this.pacoplay) super.disaggregateFlags(flags);
+    else {
+      this.castleFlags = flags[0];
+      this.pawnFlags = flags[1];
+    }
   }
 
   getUmove(move) {
   }
 
   getUmove(move) {
@@ -201,15 +222,18 @@ export class PacosakoRules extends ChessRules {
 
   static GenRandInitFen(options) {
     // Add 16 pawns flags + empty umove:
 
   static GenRandInitFen(options) {
     // Add 16 pawns flags + empty umove:
-    return ChessRules.GenRandInitFen(options)
-      .slice(0, -2) + "1111111111111111 - -";
+    const pawnFlags = (options.pacoplay ? "" : "1111111111111111");
+    return ChessRules.GenRandInitFen(options).slice(0, -2) +
+      pawnFlags + " -" + (!options.pacoplay ? " -" : "");
   }
 
   getFlagsFen() {
     let fen = super.getFlagsFen();
   }
 
   getFlagsFen() {
     let fen = super.getFlagsFen();
-    // Add pawns flags
-    for (let c of ["w", "b"])
-      for (let i = 0; i < 8; i++) fen += (this.pawnFlags[c][i] ? "1" : "0");
+    if (!this.pacoplay) {
+      // Add pawns flags
+      for (let c of ["w", "b"])
+        for (let i = 0; i < 8; i++) fen += (this.pawnFlags[c][i] ? "1" : "0");
+    }
     return fen;
   }
 
     return fen;
   }
 
@@ -224,11 +248,13 @@ export class PacosakoRules extends ChessRules {
   }
 
   getFen() {
   }
 
   getFen() {
-    return super.getFen() + " " + this.getUmoveFen();
+    const umoveFen = this.pacoplay ? "" : (" " + this.getUmoveFen());
+    return super.getFen() + umoveFen;
   }
 
   getFenForRepeat() {
   }
 
   getFenForRepeat() {
-    return super.getFenForRepeat() + "_" + this.getUmoveFen();
+    const umoveFen = this.pacoplay ? "" : ("_" + this.getUmoveFen());
+    return super.getFenForRepeat() + umoveFen;
   }
 
   getColor(i, j) {
   }
 
   getColor(i, j) {
@@ -382,7 +408,8 @@ export class PacosakoRules extends ChessRules {
             (
               m.start.x == firstRank ||
               Math.abs(m.end.x - m.start.x) == 1 ||
             (
               m.start.x == firstRank ||
               Math.abs(m.end.x - m.start.x) == 1 ||
-              this.pawnFlags[c][m.start.y]
+              this.pacoplay ||
+              (!this.pacoplay && this.pawnFlags[c][m.start.y])
             )
             &&
             (
             )
             &&
             (
@@ -471,6 +498,20 @@ export class PacosakoRules extends ChessRules {
     return moves;
   }
 
     return moves;
   }
 
+  getPotentialKingMoves(sq) {
+    if (!this.pacoplay) return super.getPotentialKingMoves(sq);
+    // Initialize with normal moves, without captures
+    let moves = [];
+    for (let s of V.steps[V.ROOK].concat(V.steps[V.BISHOP])) {
+      const [i, j] = [sq[0] + s[0], sq[1] + s[1]];
+      if (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY)
+        moves.push(this.getBasicMove(sq, [i, j]));
+    }
+    if (this.castleFlags[this.turn].some(v => v < V.size.y))
+      moves = moves.concat(this.getCastleMoves(sq));
+    return moves;
+  }
+
   getEpSquare(moveOrSquare) {
     if (typeof moveOrSquare === "string") {
       const square = moveOrSquare;
   getEpSquare(moveOrSquare) {
     if (typeof moveOrSquare === "string") {
       const square = moveOrSquare;
@@ -710,9 +751,9 @@ export class PacosakoRules extends ChessRules {
 
   filterValid(moves) {
     if (moves.length == 0) return [];
 
   filterValid(moves) {
     if (moves.length == 0) return [];
-    const L = this.umoves.length; //at least 1: init from FEN
+    const L = (!this.pacoplay ? this.umoves.length : 0);
     return moves.filter(m => {
     return moves.filter(m => {
-      if (this.oppositeMoves(this.umoves[L - 1], m)) return false;
+      if (L > 0 && this.oppositeMoves(this.umoves[L - 1], m)) return false;
       if (!m.end.released) return true;
       // Check for repetitions:
       V.PlayOnBoard(this.board, m);
       if (!m.end.released) return true;
       // Check for repetitions:
       V.PlayOnBoard(this.board, m);
@@ -775,6 +816,7 @@ export class PacosakoRules extends ChessRules {
     this.updateCastleFlags(move, piece);
     const pawnFirstRank = (c == 'w' ? 6 : 1);
     if (
     this.updateCastleFlags(move, piece);
     const pawnFirstRank = (c == 'w' ? 6 : 1);
     if (
+      !this.pacoplay &&
       move.start.x == pawnFirstRank &&
       piece == V.PAWN &&
       Math.abs(move.end.x - move.start.x) == 2
       move.start.x == pawnFirstRank &&
       piece == V.PAWN &&
       Math.abs(move.end.x - move.start.x) == 2
@@ -803,7 +845,7 @@ export class PacosakoRules extends ChessRules {
       });
     }
     V.PlayOnBoard(this.board, move);
       });
     }
     V.PlayOnBoard(this.board, move);
-    this.umoves.push(this.getUmove(move));
+    if (!this.pacoplay) this.umoves.push(this.getUmove(move));
     if (!move.end.released) this.repetitions = [];
     else {
       this.repetitions.push(
     if (!move.end.released) this.repetitions = [];
     else {
       this.repetitions.push(
@@ -825,7 +867,7 @@ export class PacosakoRules extends ChessRules {
       this.turn = V.GetOppCol(this.turn);
       this.movesCount--;
     }
       this.turn = V.GetOppCol(this.turn);
       this.movesCount--;
     }
-    this.umoves.pop();
+    if (!this.pacoplay) this.umoves.pop();
     if (!!move.end.released) this.repetitions.pop();
     this.postUndo(move);
   }
     if (!!move.end.released) this.repetitions.pop();
     this.postUndo(move);
   }