Fix Musketeer, Joker, Shinobi. Start draft of Cwda
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 11 Apr 2021 15:41:51 +0000 (17:41 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 11 Apr 2021 15:41:51 +0000 (17:41 +0200)
28 files changed:
client/public/images/pieces/Cwda/ba.svg [moved from client/public/images/pieces/Colorbound/ba.svg with 100% similarity]
client/public/images/pieces/Cwda/bd.svg [moved from client/public/images/pieces/Colorbound/bd.svg with 100% similarity]
client/public/images/pieces/Cwda/bh.svg [moved from client/public/images/pieces/Colorbound/bh.svg with 100% similarity]
client/public/images/pieces/Cwda/bs.svg [moved from client/public/images/pieces/Colorbound/bs.svg with 100% similarity]
client/public/images/pieces/Cwda/wa.svg [moved from client/public/images/pieces/Colorbound/wa.svg with 100% similarity]
client/public/images/pieces/Cwda/wd.svg [moved from client/public/images/pieces/Colorbound/wd.svg with 100% similarity]
client/public/images/pieces/Cwda/wh.svg [moved from client/public/images/pieces/Colorbound/wh.svg with 100% similarity]
client/public/images/pieces/Cwda/ws.svg [moved from client/public/images/pieces/Colorbound/ws.svg with 100% similarity]
client/public/images/pieces/Musketeer/bf.svg
client/src/base_rules.js
client/src/translations/en.js
client/src/translations/es.js
client/src/translations/fr.js
client/src/translations/rules/Cwda/en.pug [moved from client/src/translations/rules/Colorbound/en.pug with 98% similarity]
client/src/translations/rules/Cwda/es.pug [moved from client/src/translations/rules/Colorbound/es.pug with 100% similarity]
client/src/translations/rules/Cwda/fr.pug [moved from client/src/translations/rules/Colorbound/fr.pug with 100% similarity]
client/src/translations/rules/Musketeer/en.pug
client/src/translations/rules/Musketeer/es.pug
client/src/translations/rules/Musketeer/fr.pug
client/src/translations/rules/Shinobi/en.pug
client/src/translations/rules/Shinobi/es.pug
client/src/translations/rules/Shinobi/fr.pug
client/src/variants/Cwda.js [moved from client/src/variants/Colorbound.js with 98% similarity]
client/src/variants/Joker.js
client/src/variants/Musketeer.js
client/src/variants/Shinobi.js
client/src/variants/Suction.js
server/db/populate.sql

index be83f16..e1c7520 100644 (file)
@@ -15,7 +15,7 @@
    style="enable-background:new 0 0 512 512;"
    xml:space="preserve"
    sodipodi:docname="bf.svg"
-   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07, custom)"><metadata
+   inkscape:version="1.0.2 (e86c870879, 2021-01-15)"><metadata
    id="metadata55"><rdf:RDF><cc:Work
        rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
          rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
    showgrid="false"
    inkscape:zoom="1.7246094"
    inkscape:cx="256"
-   inkscape:cy="267.61097"
+   inkscape:cy="267.03113"
    inkscape:window-x="0"
    inkscape:window-y="20"
    inkscape:window-maximized="0"
-   inkscape:current-layer="Layer_1" />
+   inkscape:current-layer="Layer_1"
+   inkscape:document-rotation="0" />
 <g
    id="g6"
    transform="matrix(0.8,0,0,0.9,51.2,25.60005)">
    id="g48"
    transform="matrix(0.8,0,0,0.9,51.2,25.60005)">
 </g>
-</svg>
+<path
+   style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+   d="m 82.3656,195.89535 27.08499,-0.19092"
+   id="path30" /><path
+   style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+   d="m 84.8264,466.36515 28.82942,-8.41439"
+   id="path32" /><path
+   style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+   d="m 402.25665,456.82991 25.81837,7.47048"
+   id="path34" /><path
+   style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+   d="m 402.81172,197.15113 26.12974,-0.15998"
+   id="path36" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 84.769685,464.93962 c -0.169384,-0.27406 -0.72069,-2.67398 -1.225124,-5.33314 -0.819053,-4.3177 -0.917152,-18.61769 -0.917152,-133.69472 V 197.05187 l 9.132503,-0.37877 c 5.022876,-0.20832 10.891508,-0.37963 13.041398,-0.3807 l 3.90889,-0.002 0.15836,129.73953 c 0.0871,71.35673 0.36917,130.2824 0.62682,130.94592 0.44171,1.13755 -0.18765,1.39848 -11.025353,4.57108 -6.321594,1.85057 -11.920984,3.48308 -12.443089,3.6278 -0.522106,0.14472 -1.087869,0.0389 -1.257253,-0.23518 z"
+   id="path38" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 414.58663,459.59057 c -9.14898,-2.6478 -11.58663,-3.55827 -11.5485,-4.31344 0.0266,-0.52647 0.0918,-58.62245 0.14496,-129.10217 L 403.27973,198.03 h 13.04643 13.04643 l -0.0271,128.57984 c -0.028,133.07546 -0.076,135.92058 -2.2955,136.22005 -0.47661,0.0643 -6.08513,-1.39338 -12.46339,-3.23932 z"
+   id="path40" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 283.25943,223.39806 c 0.007,-18.92569 0.23713,-20.84998 3.21562,-26.93779 2.38937,-4.88371 7.74196,-10.23106 12.68784,-12.67545 15.56023,-7.69028 33.12587,3.2046 36.25493,22.48669 0.32534,2.00488 0.59351,10.62508 0.59592,19.156 l 0.004,15.51075 h -26.38279 -26.38278 z"
+   id="path42" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 175.98626,225.42751 c 0.002,-8.53092 0.27058,-17.15112 0.59592,-19.156 3.12431,-19.25277 20.69605,-30.1763 36.20895,-22.50941 6.93165,3.4258 12.02003,9.5049 14.51575,17.342 1.40361,4.40764 1.44057,4.97665 1.44057,22.17893 v 17.65523 h -26.38278 -26.38279 z"
+   id="path44" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 189.46537,393.87144 c 0.19048,-36.90965 0.33673,-42.51437 1.22933,-47.11211 2.26677,-11.676 7.83432,-24.63854 14.28918,-33.26856 4.04846,-5.41269 11.78337,-12.9453 16.67779,-16.2416 4.3888,-2.95577 13.19056,-7.21637 17.37797,-8.41202 l 3.04417,-0.86922 v 73.89853 73.89853 h -26.41732 -26.41732 z"
+   id="path46" /><path
+   style="fill:#ffffff;stroke:#000000;stroke-width:0.579841"
+   d="m 269.91619,361.86646 v -73.89853 l 3.04417,0.86922 c 4.50774,1.28712 13.28864,5.62335 18.04325,8.9102 4.43587,3.06652 12.26992,10.65442 15.74104,15.24646 4.84846,6.41414 9.78303,16.33863 12.3893,24.91759 3.11328,10.24788 3.16138,11.03945 3.40022,55.96004 l 0.22274,41.89355 h -26.42036 -26.42036 z"
+   id="path48" /></svg>
index 43f9f26..0c20b59 100644 (file)
@@ -368,7 +368,8 @@ export const ChessRules = class ChessRules {
 
   // Setup the initial random (asymmetric) position
   static GenRandInitFen(options) {
-    if (!options.randomness || options.randomness == 0)
+    const randomness = parseInt(options.randomness, 10);
+    if (!randomness || randomness == 0)
       // Deterministic:
       return "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w 0 ahah -";
 
index 133a0de..832bcb9 100644 (file)
@@ -273,6 +273,7 @@ export const translations = {
   "Moving forward": "Moving forward",
   "Neverending rows": "Neverending rows",
   "New fairy pieces": "New fairy pieces",
+  "New teams": "New teams",
   "No paralyzed pieces": "No paralyzed pieces",
   "No-check mode": "No-check mode",
   "Noise and confusion (v1)": "Noise and confusion (v1)",
@@ -324,7 +325,6 @@ export const translations = {
   "Thai Chess (v1)": "Thai Chess (v1)",
   "Thai Chess (v2)": "Thai Chess (v2)",
   "Thai Chess (v3)": "Thai Chess (v3)",
-  "The colorbound clobberers": "The colorbound clobberers",
   "The end of the world": "The end of the world",
   "Transform an essay": "Transform an essay",
   "Two kings": "Two kings",
index d3be2c1..4c458fb 100644 (file)
@@ -273,6 +273,7 @@ export const translations = {
   "Moving forward": "Ir adelante",
   "Neverending rows": "Filas interminables",
   "New fairy pieces": "Nuevas piezas magicas",
+  "New teams": "Nuevos equipos",
   "No paralyzed pieces": "No piezas paralizadas",
   "No-check mode": "Modo sin jaque",
   "Noise and confusion (v1)": "Ruido y confusión (v1)",
@@ -324,7 +325,6 @@ export const translations = {
   "Thai Chess (v1)": "Ajedrez tailandés (v1)",
   "Thai Chess (v2)": "Ajedrez tailandés (v2)",
   "Thai Chess (v3)": "Ajedrez tailandés (v3)",
-  "The colorbound clobberers": "Los batidores unicolor",
   "The end of the world": "El fin del mundo",
   "Transform an essay": "Transformar un ensayo",
   "Two kings": "Dos reyes",
index 3cef19e..5d3dbf1 100644 (file)
@@ -273,6 +273,7 @@ export const translations = {
   "Moving forward": "Aller de l'avant",
   "Neverending rows": "Rangées sans fin",
   "New fairy pieces": "Nouvelles pièces féériques",
+  "New teams": "Nouvelles équipes",
   "No paralyzed pieces": "Pas de pièces paralysées",
   "No-check mode": "Mode sans échec",
   "Noise and confusion (v1)": "Bruit et confusion (v1)",
@@ -324,7 +325,6 @@ export const translations = {
   "Thai Chess (v1)": "Échecs thai (v1)",
   "Thai Chess (v2)": "Échecs thai (v2)",
   "Thai Chess (v3)": "Échecs thai (v3)",
-  "The colorbound clobberers": "Les tabasseurs unicolores",
   "The end of the world": "La fin du monde",
   "Transform an essay": "Transformer un essai",
   "Two kings": "Deux rois",
similarity index 98%
rename from client/src/translations/rules/Colorbound/en.pug
rename to client/src/translations/rules/Cwda/en.pug
index 091d83c..603c8d7 100644 (file)
@@ -1,4 +1,5 @@
 p.boxed
+  | TODO: other armies as well
   | Black pieces are replaced by a new army, where most pieces are quite
   | colorbound.
 
index e90cbe9..11b265c 100644 (file)
@@ -62,7 +62,7 @@ ul
   li Cannon (C) = King + Wide Knight + Dabbabah
   li Unicorn (U) = Knight + Camel
   li Elephant (E) = King + Alfil + Dabbabh
-  li Hawk (H) = Alfil + Tripper
+  li Hawk (H) = Jumps 2 or 3 squares in any direction
   li Fortress (F) = Narrow Knight + Dabbabah + Bishop[3]
   li Spider (S) = Knight + Dabbabah + Bishop[2]
 
@@ -70,9 +70,6 @@ p With
 ul
   li Alfil = two squares leaper in diagonal
   li Dabbabah = 2 squares leaper orthogonally
-  li
-    a(href="http://gambiter.com/chess/variants/Tripper_chess.html") Tripper
-    | &nbsp;= 3 squares leaper diagonally
   li.
     Camel = extended Knight,
     3 squares in one direction and then 1 to the side
index 3a1534d..f5d0fcd 100644 (file)
@@ -65,7 +65,7 @@ ul
   li Canon (C) = Rey + Wide Knight + Dabbabah
   li Unicornio (U) = Caballo + Camello
   li Elefante (E) = Rey + Alfil + Dabbabah
-  li Halcón (H) = Alfil + Tripper
+  li Halcón (H) = Salta 2 o 3 casillas en cualquier dirección
   li Fortaleza (F) = Narrow Knight + Dabbabah + Alfil[3]
   li Araña (S) = Caballo + Dabbabah + Alfil[2]
 
index de221b2..7fd4825 100644 (file)
@@ -66,7 +66,7 @@ ul
   li Canon (C) = Roi + Wide Knight + Dabbabah
   li Licorne (U) = Cavalier + Chameau
   li Éléphant (E) = Roi + Alfil + Dabbabah
-  li Faucon (H) = Alfil + Tripper
+  li Faucon (H) = Saute 2 ou 3 cases dans n'importe quelle direction
   li Forteresse (F) = Narrow Knight + Dabbabah + Fou[3]
   li Araignée (S) = Cavalier + Dabbabah + Fou[2]
 
index 0b55d72..ec54eb0 100644 (file)
@@ -4,18 +4,18 @@ p.boxed.
 
 figure.diagram-container
   .diagram
-    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/3CK3:
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/LH1CK1HL:
   figcaption Deterministic initial position.
 
 p.
   Shinobi Chess is a chess variant designed in 2021 by Couch Tomato.
   The chess army (the "Kingdom", black) has invaded the land of the Sakura
-  Clan ("pink"). While initially unprepared and having very few pieces
+  Clan ("pink"). While initially unprepared and having few pieces
   available, the Clan is very resourceful and can instantly recruit and
   summon allies to defend at a minute's notice!
 
 p.
-  The Clan starts with almost all of its pieces in hand, and can drop them
+  The Clan starts with many of its pieces in hand, and can drop them
   on its side of the board (first 4 ranks) in lieu of moving a piece.
 
 p
index e15dcd1..1f69a12 100644 (file)
@@ -4,18 +4,18 @@ p.boxed.
 
 figure.diagram-container
   .diagram
-    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/3CK3:
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/LH1CK1HL:
   figcaption Posición inicial determinista.
 
 p.
   Ajedrez Shinobi es una variación desarrollada por Couch Tomato en 2021.
   El ejército ortodoxo (el "Reino", negras) invadió las tierras del Clan
-  Sakura ("rosa"). Aunque inicialmente no estaba preparado y con poca
-  recursos, el Clan no debe ser subestimado porque puede reclutar
+  Sakura ("rosa"). Aunque inicialmente no estaba preparado y con pocas
+  piezas, el Clan no debe ser subestimado porque puede reclutar
   nuevos aliados sin demora!
 
 p.
-  El Clan comienza con casi todas sus piezas en la mano y puede las
+  El Clan comienza con muchas de sus piezas en la mano y puede las
   paracaídas en su lado del tablero (primeras 4 filas) en lugar de
   mover una pieza.
 
index ae6a9db..ab57aa2 100644 (file)
@@ -4,7 +4,7 @@ p.boxed.
 
 figure.diagram-container
   .diagram
-    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/3CK3:
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/LH1CK1HL:
   figcaption Position initiale déterministe.
 
 p.
@@ -15,7 +15,7 @@ p.
   nouveaux alliés sans délais !
 
 p.
-  Le Clan démarre avec presque toutes ses pièces en main, et peut les
+  Le Clan démarre avec beaucoup de ses pièces en main, et peut les
   parachuter de son côté de l'échiquier (4 premières rangées) au lieu de
   déplacer une pièce.
 
similarity index 98%
rename from client/src/variants/Colorbound.js
rename to client/src/variants/Cwda.js
index 90e54dc..6e30e68 100644 (file)
@@ -2,7 +2,7 @@ import { ChessRules, Move, PiPo } from "@/base_rules";
 import { ArrayFun } from "@/utils/array";
 import { randInt } from "@/utils/alea";
 
-export class ColorboundRules extends ChessRules {
+export class CwdaRules extends ChessRules {
 
   static get PawnSpecs() {
     return Object.assign(
@@ -18,7 +18,7 @@ export class ColorboundRules extends ChessRules {
 
   getPpath(b) {
     if ([V.C_ROOK, V.C_KNIGHT, V.C_BISHOP, V.C_QUEEN].includes(b[1]))
-      return "Colorbound/" + b;
+      return "Cwda/" + b;
     return b;
   }
 
index 137249c..fd302bb 100644 (file)
@@ -76,6 +76,19 @@ export class JokerRules extends ChessRules {
     return moving.concat(swapping);
   }
 
+  postPlay(move) {
+    super.postPlay(move);
+    // Was my king swapped?
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[move.appear[1].c] = [move.appear[1].x, move.appear[1].y];
+  }
+
+  postUndo(move) {
+    super.postUndo(move);
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
+  }
+
   static get VALUES() {
     return Object.assign({ j: 2 }, ChessRules.VALUES);
   }
index 7fa3930..14ba919 100644 (file)
@@ -328,19 +328,19 @@ export class MusketeerRules extends ChessRules {
     outerLoop: for (let step of steps) {
       let i = x + step[0];
       let j = y + step[1];
-      let stepCounter = 1;
+      let stepCounter = 0;
       while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
         moves.push(this.getBasicMove([x, y], [i, j]));
+        stepCounter++;
         if (
           !!nbSteps &&
           // Next condition to remain compatible with super method
-          (isNaN(parseInt(nbSteps, 10)) || nbSteps >= stepCounter)
+          (stepCounter >= nbSteps || isNaN(parseInt(nbSteps, 10)))
         ) {
           continue outerLoop;
         }
         i += step[0];
         j += step[1];
-        stepCounter++;
       }
       if (V.OnBoard(i, j) && this.canTake([x, y], [i, j]))
         moves.push(this.getBasicMove([x, y], [i, j]));
index dbce82c..995d2b9 100644 (file)
@@ -60,7 +60,7 @@ export class ShinobiRules extends ChessRules {
     if (!ChessRules.IsGoodFen(fen)) return false;
     const fenParsed = V.ParseFen(fen);
     // 5) Check reserve
-    if (!fenParsed.reserve || !fenParsed.reserve.match(/^[0-2]{6,6}$/))
+    if (!fenParsed.reserve || !fenParsed.reserve.match(/^[0-2]{5,5}$/))
       return false;
     return true;
   }
@@ -74,12 +74,14 @@ export class ShinobiRules extends ChessRules {
   }
 
   // In hand initially: ninja, dragon, 2 x (monk, horse), lance, pawn.
-  static GenRandInitFen(randomness) {
-    const baseFen = ChessRules.GenRandInitFen(Math.min(randomness, 1));
-    return (
-      baseFen.substr(0, 35) + "3CK3 " +
-      "w 0 " + baseFen.substr(48, 2) + " - 112211"
-    );
+  static GenRandInitFen(options) {
+    const baseFen = ChessRules.GenRandInitFen(options);
+    const position = baseFen.substr(0, 43)
+      .replace('Q', 'C')
+      .replace(/B/g, '1')
+      .replace(/R/g, 'L')
+      .replace(/N/g, 'H');
+    return position + " w 0 " + baseFen.substr(48, 2) + " - 11211";
   }
 
   getFen() {
@@ -105,8 +107,7 @@ export class ShinobiRules extends ChessRules {
         [V.DRAGON]: reserve[1],
         [V.MONK]: reserve[2],
         [V.HORSE]: reserve[3],
-        [V.LANCE]: reserve[4],
-        [V.PAWN]: reserve[5]
+        [V.LANCE]: reserve[4]
       }
     };
   }
@@ -122,7 +123,7 @@ export class ShinobiRules extends ChessRules {
   }
 
   static get RESERVE_PIECES() {
-    return [V.NINJA, V.DRAGON, V.MONK, V.HORSE, V.LANCE, V.PAWN];
+    return [V.NINJA, V.DRAGON, V.MONK, V.HORSE, V.LANCE];
   }
 
   getReserveMoves([x, y]) {
@@ -386,7 +387,7 @@ export class ShinobiRules extends ChessRules {
         {
           c: 4,
           j: 7,
-          d: 7,
+          d: 6,
           m: 2,
           h: 2,
           l: 2
index d12f83d..2bf3ecf 100644 (file)
@@ -174,20 +174,16 @@ export class SuctionRules extends ChessRules {
 
   postPlay(move) {
     super.postPlay(move);
-    if (move.vanish.length == 2) {
-      // Was opponent king swapped?
-      if (move.vanish[1].p == V.KING)
-        this.kingPos[this.turn] = [move.appear[1].x, move.appear[1].y];
-    }
+    // Was opponent king swapped?
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[this.turn] = [move.appear[1].x, move.appear[1].y];
     this.cmoves.push(this.getCmove(move));
   }
 
   postUndo(move) {
     super.postUndo(move);
-    if (move.appear.length == 2) {
-      if (move.appear[1].p == V.KING)
-        this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
-    }
+    if (move.appear.length == 2 && move.appear[1].p == V.KING)
+      this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
     this.cmoves.pop();
   }
 
index 1cb54e6..c55a1b8 100644 (file)
@@ -48,7 +48,6 @@ insert or ignore into Variants (name, description, groupe, display) values
   ('Chess960', 'Standard rules', -1, 'Chess960'),
   ('Circular', 'Run forward', 3, 'Circular Chess'),
   ('Clorange', 'A Clockwork Orange', 20, 'Clockwork Orange'),
-  ('Colorbound', 'The colorbound clobberers', 5, 'Colorbound Clobberers'),
   ('Convert', 'Convert enemy pieces', 12, 'Convert'),
   ('Copycat', 'Borrow powers', 30, 'Copycat'),
   ('Coregal', 'Two royal pieces', 9, 'Coregal'),
@@ -56,6 +55,7 @@ insert or ignore into Variants (name, description, groupe, display) values
   ('Crazyhouse', 'Captures reborn', 20, 'Crazyhouse'),
   ('Crossing', 'Cross the river', 27, 'Crossing'),
   ('Cylinder', 'Neverending rows', 3, 'Cylindrical Chess'),
+  ('Cwda', 'New teams', 5, 'Different armies'),
   ('Diamond', 'Rotating board', 4, 'Diamond'),
   ('Discoduel', 'Enter the disco', 0, 'Disco Duel'),
   ('Dobutsu', 'Let''s catch the Lion!', 0, 'Dobutsu'),