Add Relayup
authorBenjamin Auder <benjamin.auder@somewhere>
Sat, 9 Jan 2021 23:49:50 +0000 (00:49 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Sat, 9 Jan 2021 23:49:50 +0000 (00:49 +0100)
13 files changed:
client/src/base_rules.js
client/src/translations/en.js
client/src/translations/es.js
client/src/translations/fr.js
client/src/translations/rules/Relayup/en.pug [new file with mode: 0644]
client/src/translations/rules/Relayup/es.pug [new file with mode: 0644]
client/src/translations/rules/Relayup/fr.pug [new file with mode: 0644]
client/src/translations/variants/en.pug
client/src/translations/variants/es.pug
client/src/translations/variants/fr.pug
client/src/variants/Pacosako.js
client/src/variants/Relayup.js
server/db/populate.sql

index 6502679..f1049b0 100644 (file)
@@ -1073,8 +1073,7 @@ console.log("ddd");
         V.OnBoard(rx, ry) &&
         this.board[rx][ry] != V.EMPTY &&
         this.getPiece(rx, ry) == piece &&
         V.OnBoard(rx, ry) &&
         this.board[rx][ry] != V.EMPTY &&
         this.getPiece(rx, ry) == piece &&
-        this.getColor(rx, ry) == color &&
-        this.canTake([rx, ry], [x, y]) //for Paco-Sako (TODO: necessary?)
+        this.getColor(rx, ry) == color
       ) {
         return true;
       }
       ) {
         return true;
       }
index a2f1eaf..5f8d341 100644 (file)
@@ -292,6 +292,7 @@ export const translations = {
   "Two kings": "Two kings",
   "Two royal pieces": "Two royal pieces",
   "Unidentified pieces": "Unidentified pieces",
   "Two kings": "Two kings",
   "Two royal pieces": "Two royal pieces",
   "Unidentified pieces": "Unidentified pieces",
+  "Upgrade pieces": "Upgrade pieces",
   "Walk on a graph": "Walk on a graph",
   "White move twice": "White move twice",
   "Win by castling long": "Win by castling long",
   "Walk on a graph": "Walk on a graph",
   "White move twice": "White move twice",
   "Win by castling long": "Win by castling long",
index 97dbec1..be0974a 100644 (file)
@@ -292,6 +292,7 @@ export const translations = {
   "Two kings": "Dos reyes",
   "Two royal pieces": "Dos piezas reales",
   "Unidentified pieces": "Piezas no identificadas",
   "Two kings": "Dos reyes",
   "Two royal pieces": "Dos piezas reales",
   "Unidentified pieces": "Piezas no identificadas",
+  "Upgrade pieces": "Aumentar piezas",
   "Walk on a graph": "Camino en un gráfico",
   "White move twice": "Las blancas juegan dos veces",
   "Win by castling long": "Ganar jugando al enroque largo",
   "Walk on a graph": "Camino en un gráfico",
   "White move twice": "Las blancas juegan dos veces",
   "Win by castling long": "Ganar jugando al enroque largo",
index 98706b9..4b6a2f7 100644 (file)
@@ -291,6 +291,7 @@ export const translations = {
   "Two kings": "Deux rois",
   "Two royal pieces": "Deux pièces royales",
   "Unidentified pieces": "Pièces non identifiées",
   "Two kings": "Deux rois",
   "Two royal pieces": "Deux pièces royales",
   "Unidentified pieces": "Pièces non identifiées",
+  "Upgrade pieces": "Augmenter les pièces",
   "Walk on a graph": "Marche sur un graphe",
   "White move twice": "Les blancs jouent deux fois",
   "Win by castling long": "Gagnez en jouant grand roque",
   "Walk on a graph": "Marche sur un graphe",
   "White move twice": "Les blancs jouent deux fois",
   "Win by castling long": "Gagnez en jouant grand roque",
diff --git a/client/src/translations/rules/Relayup/en.pug b/client/src/translations/rules/Relayup/en.pug
new file mode 100644 (file)
index 0000000..a45fc58
--- /dev/null
@@ -0,0 +1,32 @@
+p.boxed
+  | Pieces inherit the movement of friendly pieces observing them.
+
+p
+  | This variant is based on 
+  a(href="https://www.chessvariants.com/rules/relay-chess") Relay Chess
+  | &nbsp;from chessvariants.com by Johnny Luken (2012).
+
+p.
+  As in Relay Chess, there is no castle or en passant captures, and pawns
+  can only advance one square forward (by themselves).
+
+p However, I made two substantial changes:
+ul
+  li.
+    Being relayed by a friendly piece adds moving options, without canceling
+    the base movements of a piece. Thus the relay is an "upgrade", explaining
+    the chosen name "Relayup".
+  li.
+    Pawns relayed by any friendly piece (except pawns) gain the ability to
+    move and capture like it, but by one step only.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR c3,d4,d3,e3,f4,f3,g3:
+  figcaption.
+    Movements of the e2 pawn, relayed by knight and queen (+ king and bishop).
+
+p.
+  Finally, since stalemate counts as a win and (I believe) no fully blocked
+  positions can be reached, the goal is now to capture the enemy king.
+  You can theoretically go or remain into check.
diff --git a/client/src/translations/rules/Relayup/es.pug b/client/src/translations/rules/Relayup/es.pug
new file mode 100644 (file)
index 0000000..7281e62
--- /dev/null
@@ -0,0 +1,33 @@
+p.boxed
+  | Las piezas heredan los movimientos de las piezas amigas observándolas.
+
+p
+  | Esta variante se basa en 
+  a(href="https://www.chessvariants.com/rules/relay-chess") Relay Chess
+  | &nbsp;de chessvariants.com por Johnny Luken (2012).
+
+p.
+  Como en Relay Chess, no hay enroque ni captura en passant, y los peones
+  solo pueden avanzar una casilla (por sí mismos).
+
+p Sin embargo, hice dos cambios sustanciales:
+ul
+  li.
+    Ser transmitido por una parte amiga agrega capacidades de movimiento, sin
+    cancelar los movimientos básicos de una pieza. Entonces el relé
+    corresponde a un "upgrade", explicando el nombre elegido "Relayup".
+  li.
+    Peones transmitidos por cualquier pieza amiga (excepto los peones)
+    ganar la oportunidad de moverse y capturar como ellos, pero
+    con solo un paso.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR c3,d4,d3,e3,f4,f3,g3:
+  figcaption.
+    Movimientos del peón e2, transmitidos por caballo y dama (+ rey y alfil).
+
+p.
+  Finalmente, dado que el empate cuenta como una victoria y (creo)
+  no hay configuraciones completamente bloqueadas, el objetivo es capturar
+  el rey. Tiene derecho a ir o permanecer en jaque.
diff --git a/client/src/translations/rules/Relayup/fr.pug b/client/src/translations/rules/Relayup/fr.pug
new file mode 100644 (file)
index 0000000..d3e21ac
--- /dev/null
@@ -0,0 +1,33 @@
+p.boxed
+  | Les pièces héritent des mouvements des pièces amies les observant.
+
+p
+  | Cette variante est basée sur 
+  a(href="https://www.chessvariants.com/rules/relay-chess") Relay Chess
+  | &nbsp;de chessvariants.com par Johnny Luken (2012).
+
+p.
+  Comme dans Relay Chess, il n'y a ni roque ni prise en passant, et les pions
+  ne peuvent avancer que d'une case vers l'avant (par eux-mêmes).
+
+p Cependant, j'ai effectué deux changements substantiels :
+ul
+  li.
+    Être relayé par une pièce amie ajoute des capacités de déplacement, sans
+    annuler les mouvements de base d'une pièce. Ainsi le relai correspond à
+    un "upgrade", expliquant le nom choisi "Relayup".
+  li.
+    Les pions relayés par n'importe quelle pièce amie (sauf les pions)
+    gagnent la possibilité de se déplacer et capturer comme elles, mais
+    d'un pas seulement.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR c3,d4,d3,e3,f4,f3,g3:
+  figcaption.
+    Déplacements du pion e2, relayé par cavalier et dame (+ roi et fou).
+
+p.
+  Enfin, puisque le pat compte comme une victoire et que (je crois) il
+  n'existe pas de configurations complètement bloquées, le but est de capturer
+  le roi. Vous avez le droit d'aller ou de rester en échec.
index 0ac4346..53f210e 100644 (file)
@@ -409,6 +409,7 @@ p.
     "Otage",
     "Pacosako",
     "Parachute",
     "Otage",
     "Pacosako",
     "Parachute",
+    "Relayup",
     "Screen",
     "Takenmake",
     "Titan",
     "Screen",
     "Takenmake",
     "Titan",
index 761b739..c1123f7 100644 (file)
@@ -420,6 +420,7 @@ p.
     "Otage",
     "Pacosako",
     "Parachute",
     "Otage",
     "Pacosako",
     "Parachute",
+    "Relayup",
     "Screen",
     "Takenmake",
     "Titan",
     "Screen",
     "Takenmake",
     "Titan",
index 232691d..c0b0ee7 100644 (file)
@@ -419,6 +419,7 @@ p.
     "Otage",
     "Pacosako",
     "Parachute",
     "Otage",
     "Pacosako",
     "Parachute",
+    "Relayup",
     "Screen",
     "Takenmake",
     "Titan",
     "Screen",
     "Takenmake",
     "Titan",
index 9f0abf8..b67d429 100644 (file)
@@ -666,6 +666,28 @@ export class PacosakoRules extends ChessRules {
     return res;
   }
 
     return res;
   }
 
+  isAttackedBySlideNJump([x, y], color, piece, steps, oneStep) {
+    for (let step of steps) {
+      let rx = x + step[0],
+          ry = y + step[1];
+      while (V.OnBoard(rx, ry) && this.board[rx][ry] == V.EMPTY && !oneStep) {
+        rx += step[0];
+        ry += step[1];
+      }
+      if (
+        V.OnBoard(rx, ry) &&
+        this.board[rx][ry] != V.EMPTY &&
+        this.getPiece(rx, ry) == piece &&
+        this.getColor(rx, ry) == color &&
+        this.canTake([rx, ry], [x, y]) //TODO: necessary line?
+                                       //If not, generic method is OK
+      ) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   // Do not consider checks, except to forbid castling
   getCheckSquares() {
     return [];
   // Do not consider checks, except to forbid castling
   getCheckSquares() {
     return [];
index 4b85fde..446c927 100644 (file)
@@ -1,6 +1,6 @@
 import { ChessRules } from "@/base_rules";
 
 import { ChessRules } from "@/base_rules";
 
-// Pawns relayed by one square at a time (but with relaying pioece movements)
+// Pawns relayed by one square at a time (but with relaying piece movements)
 // diff from https://www.chessvariants.com/rules/relay-chess ==> new name
 export class RelayupRules extends ChessRules {
 
 // diff from https://www.chessvariants.com/rules/relay-chess ==> new name
 export class RelayupRules extends ChessRules {
 
@@ -22,13 +22,69 @@ export class RelayupRules extends ChessRules {
 
   getPotentialMovesFrom([x, y]) {
     let moves = super.getPotentialMovesFrom([x, y]);
 
   getPotentialMovesFrom([x, y]) {
     let moves = super.getPotentialMovesFrom([x, y]);
+    // Expand potential moves if guarded by friendly pieces.
+    // NOTE: pawns cannot be promoted through a relaying move
+    const piece = this.getPiece(x,y);
+    const color = this.turn;
+    const lastRank = (color == 'w' ? 0 : 7);
+    const sq = [x, y];
+    const oneStep = (piece == V.PAWN);
+    let guardedBy = {};
+    if (piece != V.ROOK && super.isAttackedByRook(sq, color))
+      guardedBy[V.ROOK] = true;
+    if (piece != V.KNIGHT && super.isAttackedByKnight(sq, color))
+      guardedBy[V.KNIGHT] = true;
+    if (piece != V.BISHOP && super.isAttackedByBishop(sq, color))
+      guardedBy[V.BISHOP] = true;
+    if (piece != V.QUEEN && super.isAttackedByQueen(sq, color))
+      guardedBy[V.QUEEN] = true;
+    if (piece != V.KING && super.isAttackedByKing(sq, color))
+      guardedBy[V.KING] = true;
+    Object.keys(guardedBy).forEach(pg => {
+      let steps = null;
+      if ([V.ROOK, V.KNIGHT, V.BISHOP].includes(pg)) steps = V.steps[pg];
+      else steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
+      const extraMoves =
+        super.getSlideNJumpMoves(
+          sq, steps, oneStep || [V.KNIGHT, V.KING].includes(pg))
+        .filter(m => {
+          return (
+            (piece != V.PAWN || m.end.x != lastRank) &&
+            (moves.every(mv => mv.end.x != m.end.x || mv.end.y != m.end.y))
+          );
+        });
+      moves = moves.concat(extraMoves);
+    });
+    return moves;
+  }
 
 
-    // Expand possible moves if guarded by friendly pieces:
-    // --> Pawns cannot be promoted through a relaying move (thus 8th rank forbidden)
-    // TODO
-
+  filterValid(moves) {
     return moves;
   }
     return moves;
   }
+  getCheckSquares() {
+    return [];
+  }
+
+  postPlay(move) {
+    super.postPlay(move);
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[move.vanish[1].c] = [-1, -1];
+  }
+
+  postUndo(move) {
+    super.postUndo(move);
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING) {
+      const v = move.vanish[1];
+      this.kingPos[v.c] = [v.x, v.y];
+    }
+  }
+
+  getCurrentScore() {
+    const c = this.turn;
+    if (this.kingPos[c][0] < 0) return (c == 'w' ? "0-1" : "1-0");
+    // It seems that there is always a possible move (TODO: check this)
+    return "*";
+  }
 
   getNotation(move) {
     // Translate final and initial square
 
   getNotation(move) {
     // Translate final and initial square
index 56571e5..fc81464 100644 (file)
@@ -107,6 +107,7 @@ insert or ignore into Variants (name, description) values
   ('Queenpawns', 'Queen versus pawns'),
   ('Racingkings', 'Kings cross the 8x8 board'),
   ('Rampage', 'Move under cover'),
   ('Queenpawns', 'Queen versus pawns'),
   ('Racingkings', 'Kings cross the 8x8 board'),
   ('Rampage', 'Move under cover'),
+  ('Relayup', 'Upgrade pieces'),
   ('Rifle', 'Shoot pieces'),
   ('Recycle', 'Reuse pieces'),
   ('Rococo', 'Capture on the edge'),
   ('Rifle', 'Shoot pieces'),
   ('Recycle', 'Reuse pieces'),
   ('Rococo', 'Capture on the edge'),