From 05d37cc77857fc683e431820aff39db24bd86835 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sat, 4 Apr 2020 18:52:50 +0200
Subject: [PATCH] Fix Dynamo rules: pawns cannot pull

---
 client/src/translations/rules/Dynamo/en.pug | 29 +++++++++++++--------
 client/src/translations/rules/Dynamo/es.pug | 29 +++++++++++++--------
 client/src/translations/rules/Dynamo/fr.pug | 29 +++++++++++++--------
 client/src/variants/Dynamo.js               | 25 ++++++++++++++++++
 4 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/client/src/translations/rules/Dynamo/en.pug b/client/src/translations/rules/Dynamo/en.pug
index 1deec297..ac4263c8 100644
--- a/client/src/translations/rules/Dynamo/en.pug
+++ b/client/src/translations/rules/Dynamo/en.pug
@@ -48,16 +48,12 @@ figure.diagram-container
     | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKBNR:
   figcaption Pulling the d5 pawn to c3 (left: before, right: after).
 
-figure.diagram-container
-  .diagram.diag12
-    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
-  .diagram.diag22
-    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
-  figcaption Pushing the d4 bishop to b2 (left: before, right: after).
-
-p.
-  It is forbidden to undo a "move + action". For example here, white could
-  push back the black bishop on g7 but not return to d4 then.
+ul
+  li Pawns cannot pull (because they only move forward).
+  li.
+    When they could reach the square beyond the edge,
+    pieces can exit the board by themselves, possibly dragging another piece
+    out (friendly or enemy).
 
 figure.diagram-container
   .diagram
@@ -67,7 +63,18 @@ figure.diagram-container
     diagonal.
 
 p.
-  Note: castling is possible as long as the king and rook have not moved and
+  It is forbidden to undo a "move + action". For example here, white could
+  push back the black bishop on g7 but not return to d4 then.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
+  .diagram.diag22
+    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
+  figcaption Pushing the d4 bishop to b2 (left: before, right: after).
+
+p.
+  Castling is possible as long as the king and rook have not moved and
   haven't been pushed or pulled (this differs from the chessvariants
   description).
 
diff --git a/client/src/translations/rules/Dynamo/es.pug b/client/src/translations/rules/Dynamo/es.pug
index 72bb9acc..e7843ceb 100644
--- a/client/src/translations/rules/Dynamo/es.pug
+++ b/client/src/translations/rules/Dynamo/es.pug
@@ -48,16 +48,12 @@ figure.diagram-container
     | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKBNR:
   figcaption Tirando el peón d5 hacia c3 (izquierda: antes, derecha: después).
 
-figure.diagram-container
-  .diagram.diag12
-    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
-  .diagram.diag22
-    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
-  figcaption Empujando el alfil d4 hacia b2 (izquierda: antes, derecha: después).
-
-p.
-  Está prohibido deshacer un "movimiento + acción". Por ejemplo aquí, las
-  blancas podrían empujar al alfil negro a g7, pero no regresar a d4 después.
+ul
+  li Los peones no pueden disparar (ya que solo avanzan).
+  li.
+    Cuando pudieran alcanzar la pieza más allá del borde del tablero,
+    las piezas pueden salir del juego solas, posiblemente
+    entrenando a otra afuera (amiga o enemiga).
 
 figure.diagram-container
   .diagram
@@ -67,7 +63,18 @@ figure.diagram-container
     la diagonal a4-e8
 
 p.
-  Nota: el enroque es posible si el rey y la torre no se hayan movido ni hayan
+  Está prohibido deshacer un "movimiento + acción". Por ejemplo aquí, las
+  blancas podrían empujar al alfil negro a g7, pero no regresar a d4 después.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
+  .diagram.diag22
+    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
+  figcaption Empujando el alfil d4 hacia b2 (izquierda: antes, derecha: después).
+
+p.
+  El enroque es posible si el rey y la torre no se hayan movido ni hayan
   sido sujeto a acción (esto difiere de la regla dada sobre chessvariants).
   No hay capturas en-passant.
 
diff --git a/client/src/translations/rules/Dynamo/fr.pug b/client/src/translations/rules/Dynamo/fr.pug
index 9250b12c..a31d514f 100644
--- a/client/src/translations/rules/Dynamo/fr.pug
+++ b/client/src/translations/rules/Dynamo/fr.pug
@@ -49,16 +49,12 @@ figure.diagram-container
     | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKBNR:
   figcaption Tirant le pion d5 en c3 (gauche : avant, droite : après).
 
-figure.diagram-container
-  .diagram.diag12
-    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
-  .diagram.diag22
-    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
-  figcaption Poussant le fou d4 vers b2 (gauche : avant, droite : après).
-
-p.
-  Il est interdit de défaire un "coup + action". Par exemple ici, les blancs
-  pourraient pousser le fou noir en g7, mais pas retourner sur d4 ensuite.
+ul
+  li Les pions ne peuvent pas tirer (car ils ne se déplacent qu'en avant).
+  li.
+    Quand elles pourraient atteindre la case au-delà du bord de l'échiquier,
+    les pièces peuvent sortir du jeu par elles-mêmes, éventuellement
+    en entraînant une autre en dehors (amie ou ennemie).
 
 figure.diagram-container
   .diagram
@@ -68,7 +64,18 @@ figure.diagram-container
     la diagonale a4-e8
 
 p.
-  Note : le roque est possible tant que roi et tour n'ont ni bougé ni été
+  Il est interdit de défaire un "coup + action". Par exemple ici, les blancs
+  pourraient pousser le fou noir en g7, mais pas retourner sur d4 ensuite.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqk1nr/ppppppbp/6p1/8/3B4/1P6/P1PPPPPP/RN1QKBNR:
+  .diagram.diag22
+    | fen:rnbqk1nr/pppppp1p/6p1/8/3b4/1P6/PBPPPPPP/RN1QKBNR:
+  figcaption Poussant le fou d4 vers b2 (gauche : avant, droite : après).
+
+p.
+  Le roque est possible tant que roi et tour n'ont ni bougé ni été
   sujets à une action (cela diffère de la règle donnée sur chessvariants).
   Il n'y a pas de prise en passant.
 
diff --git a/client/src/variants/Dynamo.js b/client/src/variants/Dynamo.js
index 9c0d0801..7403d061 100644
--- a/client/src/variants/Dynamo.js
+++ b/client/src/variants/Dynamo.js
@@ -208,6 +208,22 @@ export class DynamoRules extends ChessRules {
     return false;
   }
 
+  isAprioriValidVertical([x1, y1], x2) {
+    const piece = this.getPiece(x1, y1);
+    const deltaX = Math.abs(x1 - x2);
+    const startRank = (this.getColor(x1, y1) == 'w' ? 6 : 1);
+    return (
+      [V.QUEEN, V.ROOK].includes(piece) ||
+      (
+        [V.KING, V.PAWN].includes(piece) &&
+        (
+          deltaX == 1 ||
+          (deltaX == 2 && piece == V.PAWN && x1 == startRank)
+        )
+      )
+    );
+  }
+
   // NOTE: for pushes, play the pushed piece first.
   //       for pulls: play the piece doing the action first
   // NOTE: to push a piece out of the board, make it slide until its king
@@ -337,6 +353,15 @@ export class DynamoRules extends ChessRules {
         [fm.start.x - x, fm.start.y - y]);
       // Normalized directions should match
       if (dir[0] == dirM[0] && dir[1] == dirM[1]) {
+        // If first move is a pawn move, only a queen, rook, or maybe king or
+        // pawn can follow (need vertical movement option).
+        if (
+          fm.vanish[0].p == V.PAWN &&
+          fm.vanish[0].c == color &&
+          !this.isAprioriValidVertical([x, y], fm.start.x)
+        ) {
+          return [];
+        }
         // And nothing should stand between [x, y] and the square fm.start
         let [i, j] = [x + dir[0], y + dir[1]];
         while (
-- 
2.44.0