From 8c267d0c700050831a10d0934df1d1606aa0d654 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 3 Apr 2020 14:41:33 +0200
Subject: [PATCH] Fix and describe Dynamo, should now be playable (beta)

---
 TODO                                          |   4 -
 client/src/translations/rules/Dynamo/en.pug   | 101 ++++++++++++++++-
 client/src/translations/rules/Dynamo/es.pug   | 102 ++++++++++++++++-
 client/src/translations/rules/Dynamo/fr.pug   | 103 +++++++++++++++++-
 .../src/translations/rules/Synchrone/en.pug   |   2 +-
 .../src/translations/rules/Synchrone/es.pug   |   2 +-
 client/src/variants/Dynamo.js                 |  21 +++-
 7 files changed, 320 insertions(+), 15 deletions(-)
 delete mode 100644 TODO

diff --git a/TODO b/TODO
deleted file mode 100644
index d9944f24..00000000
--- a/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-Finish https://www.chessvariants.com/mvopponent.dir/dynamo.html
-https://echekk.fr/spip.php?page=article&id_article=599
-And Chakart :)
-Checkered 1 & 2, with switch?
diff --git a/client/src/translations/rules/Dynamo/en.pug b/client/src/translations/rules/Dynamo/en.pug
index 2662cdd2..52d2cf32 100644
--- a/client/src/translations/rules/Dynamo/en.pug
+++ b/client/src/translations/rules/Dynamo/en.pug
@@ -1,2 +1,99 @@
-p.boxed
-  | TODO: not playable yet!
+p.boxed.
+  Moves are potentially played in two times: move a piece,
+  and / or push or pull something with that unit.
+
+p.
+  Pieces have the same movement as in orthodox chess, except that they cannot
+  take other pieces in the usual way. Instead of the normal captures, pieces
+  can pull or push other pieces, potentially off the board.
+  The goal is to send the enemy king off the board.
+
+p Each turn, a player has the following options:
+ul
+  li.
+    Move one of his pieces normally, then optionally pull something as an
+    effect of this move.
+  li.
+    Push any piece with one of his pieces, then optionally follow the pushed
+    piece.
+
+p
+  | It seems easier to understand with some examples. For a detailed
+  | introduction please visit 
+  a(href="https://echekk.fr/spip.php?page=article&id_article=599") this page
+  | &nbsp;(in French).
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKB1R e1,e3,e4,c3,f3,g4,h5,d3,c4,b5,a6:
+  figcaption Possible "pawn moves" in the initial position.
+
+p.
+  The e2 pawn can move to e3 and e4 as usual. It can also slide diagonally,
+  being pushed by the bishop or the queen (which may or may not move along
+  this line afterward). It can also go to c3, being pushed by the knight from
+  g1; then the knight can move to e2, or stay motionless.
+  Finally, the pawn can "take the king": this is a special move indicating that
+  you want it to exit the board. Indeed it could be pushed off the board by the
+  bishop or the queen.
+
+p.
+  Note: if you don't want to play a second part in a move, just click on any
+  empty square: this will replace the second part by an empty move.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKB1R:
+  .diagram.diag22
+    | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKB1R:
+  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.
+
+figure.diagram-container
+  .diagram
+    | fen:rnb1qbnr/pppkpppp/3p4/8/Q1P5/5NP1/PP1PPP1P/RNB1KB1R:
+  figcaption.
+    Check: the queen threatens to pull the king off the board along the a4-e8
+    diagonal.
+
+p.
+  Note: 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).
+
+h3 End of the game
+
+p.
+  The game ends when a push or pull action threatens to send the king off the
+  board, and he has no way to escape it.
+
+figure.diagram-container
+  .diagram
+    | fen:8/4B3/8/8/6Qk/8/4N3/K7:
+  figcaption Dynamo checkmate ("Dynamate" :) )
+
+p.
+  The king cannot "take" on g4: this would just push the queen one step to the
+  left, and she would then push the king beyond the 'h' file.
+  There are no en-passant captures.
+
+h3 Source
+
+p
+  a(href="https://www.chessvariants.com/mvopponent.dir/dynamo.html")
+    | Dynamo chess
+  | &nbsp;on chessvariants.com. The short description given on 
+  a(href="http://www.pion.ch/echecs/variante.php?jeu=dynamo") this page
+  | &nbsp;might help too.
+
+p Inventors: Hans Kluever and Peter Kahl (1968)
diff --git a/client/src/translations/rules/Dynamo/es.pug b/client/src/translations/rules/Dynamo/es.pug
index 6fbe3756..e10c925d 100644
--- a/client/src/translations/rules/Dynamo/es.pug
+++ b/client/src/translations/rules/Dynamo/es.pug
@@ -1,2 +1,100 @@
-p.boxed
-  | TODO: no jugable en este momento!
+p.boxed.
+  Los movimientos se juegan potencialmente en dos etapas: mover una pieza,
+  y / o empujar o tirar de algo con esta unidad.
+
+p.
+  Las piezas se mueven como el ajedrez ortodoxo, pero no capturan
+  como de costumbre. En lugar de las capturas habituales, las piezas pueden
+  empujar o tirar de otras piezas, potencialmente fuera del tablero.
+  El objetivo es enviar al rey contrario fuera del tablero de ajedrez.
+
+p Cada jugador tiene las siguientes opciones en cada turno:
+ul
+  li.
+    Mueve una de sus piezas normalmente, luego posiblemente dispara
+    algo así como un efecto de jugada.
+  li.
+    Empuja cualquier pieza con una de las suyas, luego opcionalmente
+    sigue la pieza empujada.
+
+p
+  | Parece más fácil de entender con algunos ejemplos. Por una
+  | introducción detallada, ver 
+  a(href="https://echekk.fr/spip.php?page=article&id_article=599") esta página
+  | .
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKB1R e1,e3,e4,c3,f3,g4,h5,d3,c4,b5,a6:
+  figcaption Posibles "movimientos de peón" en la posición inicial.
+
+p.
+  El peón e2 puede ir a e3 o e4 como de costumbre. También puede deslizarse
+  diagonal, empujado por el alfil o la dama (que podría o no seguirlo
+  a lo largo de esta línea entonces). También puede alcanzar c3, empujado por
+  el caballo de g1; entonces el caballo puede ir a e2 o quedarse quieto.
+  Finalmente, el peón puede "tomar al rey": es un movimiento especial que
+  indica que lo quieres fuera del tablero de ajedrez. De hecho, este podría ser
+  empujado afuera por el alfil o la dama.
+
+p.
+  Nota: si no desea ejecutar un segundo movimiento, haga clic simplemente en un
+  cuadrado vacío: esto reemplazará la segunda parte con un movimiento vacío.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPPP/R1BQKB1R:
+  .diagram.diag22
+    | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKB1R:
+  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.
+
+figure.diagram-container
+  .diagram
+    | fen:rnb1qbnr/pppkpppp/3p4/8/Q1P5/5NP1/PP1PPP1P/RNB1KB1R:
+  figcaption.
+    Jaque: la dama amenaza con sacar al rey fuera del tablero de ajedrez por
+    la diagonal a4-e8
+
+p.
+  Nota: 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.
+
+h3 Fin de la partida
+
+p.
+  El juego termina cuando el rey es amenazado con salir por cierto
+  acción, y que este último no puede escapar de ella.
+
+figure.diagram-container
+  .diagram
+    | fen:8/4B3/8/8/6Qk/8/4N3/K7:
+  figcaption Jaque mate Dynamo ("Dynamate" :) )
+
+p.
+  El rey no puede "tomar" en g4: esto solo movería a la dama
+  un cuadrado a la izquierda, y luego empujaría al rey más allá del
+  columna 'h'.
+
+h3 Fuente
+
+p
+  | La 
+  a(href="https://www.chessvariants.com/mvopponent.dir/dynamo.html")
+    | variante Dynamo
+  | &nbsp;en chessvariants.com. La breve descripción dada en
+  a(href="http://www.pion.ch/echecs/variante.php?jeu=dynamo") esta página
+  | &nbsp;también podría ayudar.
+
+p Inventores: Hans Kluever y Peter Kahl (1968)
diff --git a/client/src/translations/rules/Dynamo/fr.pug b/client/src/translations/rules/Dynamo/fr.pug
index d16e4b4c..a2ce1cf0 100644
--- a/client/src/translations/rules/Dynamo/fr.pug
+++ b/client/src/translations/rules/Dynamo/fr.pug
@@ -1,2 +1,101 @@
-p.boxed
-  | TODO: pas jouable pour le moment !
+p.boxed.
+  Les coups sont potentiellement joués en deux temps : déplacez une pièce,
+  et / ou poussez ou tirez quelque chose avec cette unité.
+
+p.
+  Les pièces se déplacent comme aux échecs orthodoxes, mais ne capturent pas
+  comme d'habitude. Au lieu des captures habituelles, les pièces peuvent
+  pousser ou tirer d'autres pièces, potentiellement en dehors de l'échiquier.
+  L'objectif est d'envoyer le roi adverse hors de l'échiquier.
+
+p À chaque tour, un joueur dispose des options suivantes :
+ul
+  li.
+    Déplacer l'une de ses pièces normalement, puis éventuellement tirer
+    quelque chose comme un effet du coup.
+  li.
+    Pousser n'importe quelle pièce avec une des siennes, puis éventuellement
+    suivre la pièce poussée.
+
+p
+  | Cela semble plus facile à comprendre avec quelques exemples. Pour une
+  | introduction détaillée, allez voir 
+  a(href="https://echekk.fr/spip.php?page=article&id_article=599") cette page
+  | .
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKB1R e1,e3,e4,c3,f3,g4,h5,d3,c4,b5,a6:
+  figcaption Possibles "coups de pions" dans la position initiale.
+
+p.
+  Le pion e2 peut aller en e3 ou e4 comme d'habitude. Il peut aussi glisser en
+  diagonale, poussé par le fou ou la dame (qui pourraient ou non le suivre le
+  long de cette ligne ensuite). Il peut aussi atteindre c3, poussé par le
+  cavalier depuis g1 ; ensuite le cavalier peut aller en e2 ou rester immobile.
+  Enfin, le pion peut "prendre le roi" : c'est un coup spécial indiquant que
+  vous voulez qu'il sorte de l'échiquier. En effet celui-ci pourrait être
+  poussé en dehors par le fou ou la dame.
+
+p.
+  Note : si vous ne voulez pas exécuter une seconde partie de coup, cliquez
+  simplement sur une case vide : cela remplacera la seconde partie par un coup
+  vide.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKB1R:
+  .diagram.diag22
+    | fen:rnbqkbnr/ppp1pppp/8/8/8/2p5/PPPPPPPP/RNBQKB1R:
+  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.
+
+figure.diagram-container
+  .diagram
+    | fen:rnb1qbnr/pppkpppp/3p4/8/Q1P5/5NP1/PP1PPP1P/RNB1KB1R:
+  figcaption.
+    Échec : la dame menace de tirer le roi en dehors de l'échiqier le long de
+    la diagonale a4-e8
+
+p.
+  Note : 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.
+
+h3 Fin de la partie
+
+p.
+  La partie se termine quand le roi est menacé de sortie par une certaine
+  action, et que celui-ci ne peut s'y soustraire.
+
+figure.diagram-container
+  .diagram
+    | fen:8/4B3/8/8/6Qk/8/4N3/K7:
+  figcaption Échec et mat Dynamo ("Dynamat" :) )
+
+p.
+  Le roi ne peut pas "prendre" en g4 : cela ne ferait que déplacer la dame
+  d'une case vers la gauche, et elle pousserait ensuite le roi au-delà de la
+  colonne 'h'.
+
+h3 Source
+
+p
+  | La 
+  a(href="https://www.chessvariants.com/mvopponent.dir/dynamo.html")
+    | variante Dynamo
+  | &nbsp;sur chessvariants.com. la description courte donnée sur 
+  a(href="http://www.pion.ch/echecs/variante.php?jeu=dynamo") cette page
+  | &nbsp;pourrait aider aussi.
+
+p Inventeurs : Hans Kluever et Peter Kahl (1968)
diff --git a/client/src/translations/rules/Synchrone/en.pug b/client/src/translations/rules/Synchrone/en.pug
index b72064b4..ca4420aa 100644
--- a/client/src/translations/rules/Synchrone/en.pug
+++ b/client/src/translations/rules/Synchrone/en.pug
@@ -61,4 +61,4 @@ p
   | and disable the "exchange of captures" stage. 
   a(href="http://www.pion.ch/echecs/variante.php?jeu=synchro")
     | Another description
-  | &nbsp;(in French).
+  | .
diff --git a/client/src/translations/rules/Synchrone/es.pug b/client/src/translations/rules/Synchrone/es.pug
index d9963a21..8a6e8b5f 100644
--- a/client/src/translations/rules/Synchrone/es.pug
+++ b/client/src/translations/rules/Synchrone/es.pug
@@ -61,4 +61,4 @@ p
   | , modificado para autorizar la captura en passant y cancelar la fase de
   | "cambio de captura". 
   a(href="http://www.pion.ch/echecs/variante.php?jeu=synchro") Otra descripción
-  | &nbsp;(en francés).
+  | .
diff --git a/client/src/variants/Dynamo.js b/client/src/variants/Dynamo.js
index 53eedfd5..f7d60240 100644
--- a/client/src/variants/Dynamo.js
+++ b/client/src/variants/Dynamo.js
@@ -224,8 +224,11 @@ export class DynamoRules extends ChessRules {
         newMoves.forEach(m => { movesHash[getMoveHash(m)] = true; });
         Array.prototype.push.apply(moves, newMoves);
       };
-      // Free to play any move:
-      const moves = super.getPotentialMovesFrom([x, y])
+      // Free to play any move (if piece of my color):
+      const moves =
+        this.getColor(x, y) == color
+          ? super.getPotentialMovesFrom([x, y])
+          : [];
       const pawnShift = (color == 'w' ? -1 : 1);
       const pawnStartRank = (color == 'w' ? 6 : 1);
       // Structure to avoid adding moves twice (can be action & move)
@@ -428,7 +431,19 @@ export class DynamoRules extends ChessRules {
         this.getPiece(rx, ry) == piece &&
         this.getColor(rx, ry) == color
       ) {
-        // Now step in the other direction: if end of the world, then attacked
+        // Continue some steps in the same direction (pull)
+        rx += step[0];
+        ry += 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)) return true;
+        // Step in the other direction (push)
         rx = x - step[0];
         ry = y - step[1];
         while (
-- 
2.44.0