From 2c947b3a9b435b87781d31b0ef6e7744dd81ee1b Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 11 Dec 2020 13:56:30 +0100
Subject: [PATCH] Add Minixiangqi, fix a few typos

---
 client/src/styles/_board_squares_img.sass     |  4 +
 client/src/translations/en.js                 |  3 +-
 client/src/translations/es.js                 |  3 +-
 client/src/translations/fr.js                 |  3 +-
 .../src/translations/rules/Minishogi/en.pug   |  4 +-
 .../src/translations/rules/Minishogi/fr.pug   |  4 +-
 .../src/translations/rules/Minixiangqi/en.pug | 21 +++++
 .../src/translations/rules/Minixiangqi/es.pug | 22 +++++
 .../src/translations/rules/Minixiangqi/fr.pug | 22 +++++
 client/src/variants/Minishogi.js              |  2 +-
 client/src/variants/Minixiangqi.js            | 93 +++++++++++++++++++
 server/db/populate.sql                        |  1 +
 12 files changed, 174 insertions(+), 8 deletions(-)
 create mode 100644 client/src/translations/rules/Minixiangqi/en.pug
 create mode 100644 client/src/translations/rules/Minixiangqi/es.pug
 create mode 100644 client/src/translations/rules/Minixiangqi/fr.pug
 create mode 100644 client/src/variants/Minixiangqi.js

diff --git a/client/src/styles/_board_squares_img.sass b/client/src/styles/_board_squares_img.sass
index e082f9ec..cccce415 100644
--- a/client/src/styles/_board_squares_img.sass
+++ b/client/src/styles/_board_squares_img.sass
@@ -11,6 +11,10 @@ div.board5
   width: 20%
   padding-bottom: 20%
 
+div.board7
+  width: 14.28%
+  padding-bottom: 14.28%
+
 div.board8
   width: 12.5%
   padding-bottom: 12.5%
diff --git a/client/src/translations/en.js b/client/src/translations/en.js
index 57dcd898..708fed0a 100644
--- a/client/src/translations/en.js
+++ b/client/src/translations/en.js
@@ -279,5 +279,6 @@ export const translations = {
   "Unidentified pieces": "Unidentified pieces",
   "Walk on a graph": "Walk on a graph",
   "White move twice": "White move twice",
-  "Win by castling long": "Win by castling long"
+  "Win by castling long": "Win by castling long",
+  "Xiangqi 7 x 7": "Xiangqi 7 x 7"
 };
diff --git a/client/src/translations/es.js b/client/src/translations/es.js
index a7e3c9d4..9542c286 100644
--- a/client/src/translations/es.js
+++ b/client/src/translations/es.js
@@ -279,5 +279,6 @@ export const translations = {
   "Unidentified pieces": "Piezas no identificadas",
   "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"
+  "Win by castling long": "Ganar jugando al enroque largo",
+  "Xiangqi 7 x 7": "Xiangqi 7 x 7"
 };
diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js
index d971d6ba..4adeff38 100644
--- a/client/src/translations/fr.js
+++ b/client/src/translations/fr.js
@@ -279,5 +279,6 @@ export const translations = {
   "Unidentified pieces": "Pièces non identifiées",
   "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"
+  "Win by castling long": "Gagnez en jouant grand roque",
+  "Xiangqi 7 x 7": "Xiangqi 7 x 7"
 };
diff --git a/client/src/translations/rules/Minishogi/en.pug b/client/src/translations/rules/Minishogi/en.pug
index c4cf3133..e8ae50c1 100644
--- a/client/src/translations/rules/Minishogi/en.pug
+++ b/client/src/translations/rules/Minishogi/en.pug
@@ -6,13 +6,13 @@ figure.diagram-container
   figcaption Initial position.
 
 p.
-  Minishogi is essentially shogi on a 5x5 board. The game was invented
+  Minishogi is essentially Shogi on a 5x5 board. The game was invented
   (or rediscovered) around 1970 by Shigenobu Kusumoto of Osaka, Japan.
 
 p
   | The rules are the same as in 
   a(href="/#/variants/Shogi") Shogi
-  | . Unlike standard shogi, there is no knight or lance.
+  | . Unlike standard Shogi, there is no knight or lance.
   | Promotion is only done in the last rank.
 
 p
diff --git a/client/src/translations/rules/Minishogi/fr.pug b/client/src/translations/rules/Minishogi/fr.pug
index f4674f95..ae537053 100644
--- a/client/src/translations/rules/Minishogi/fr.pug
+++ b/client/src/translations/rules/Minishogi/fr.pug
@@ -11,10 +11,10 @@ p.
   d'Osaka, Japon.
 
 p
-  | les règles sont les mêmes qu'au 
+  | Les règles sont les mêmes qu'au 
   a(href="/#/variants/Shogi") Shogi
   | . Contrairement au Shogi standard, il n'y a ni lance ni cavalier.
-  | Les promotion ne s'effectuent que sur la dernière rangée.
+  | Les promotions ne s'effectuent que sur la dernière rangée.
 
 p
   | Voir aussi 
diff --git a/client/src/translations/rules/Minixiangqi/en.pug b/client/src/translations/rules/Minixiangqi/en.pug
new file mode 100644
index 00000000..f3a437f2
--- /dev/null
+++ b/client/src/translations/rules/Minixiangqi/en.pug
@@ -0,0 +1,21 @@
+p.boxed Xiangqi on a 7 x 7 board.
+
+figure.diagram-container
+  .diagram
+    | fen:rcnkncr/p1ppp1p/7/7/7/P1PPP1P/RCNKNCR:
+  figcaption Initial position.
+
+p.
+  Minixiangqi is essentially Xiangqi on a 7x7 board. The game was invented
+  (or rediscovered) around 1973 by Shigenobu Kusumoto of Osaka, Japan.
+
+p
+  | The rules are the same as in 
+  a(href="/#/variants/Xiangqi") Xiangqi
+  | . Unlike standard Xiangqi, there is no elephant or advisor.
+  | Pawns always have the ability to move sideways.
+
+p
+  | See also 
+  a(href="https://www.pychess.org/variant/minixiangqi") Minixiangqi
+  | &nbsp;on pychess-variants.
diff --git a/client/src/translations/rules/Minixiangqi/es.pug b/client/src/translations/rules/Minixiangqi/es.pug
new file mode 100644
index 00000000..750c6bbf
--- /dev/null
+++ b/client/src/translations/rules/Minixiangqi/es.pug
@@ -0,0 +1,22 @@
+p.boxed Xiangqi en un tablero 7 x 7.
+
+figure.diagram-container
+  .diagram
+    | fen:rcnkncr/p1ppp1p/7/7/7/P1PPP1P/RCNKNCR:
+  figcaption Posición inicial.
+
+p.
+  Esta variante corresponde al Xiangqi en un tablero de ajedrez de 7x7.
+  Este juego fue inventado (o redescubierto) en 1973 por Shigenobu Kusumoto
+  de Osaka, Japón.
+
+p
+  | Las reglas son las mismas que en 
+  a(href="/#/variants/Xiangqi") Xiangqi
+  | . A diferencia del Xiangqi estándar, no hay elefante ni consejero.
+  | Los peones siempre tienen la opción de moverse hacia los lados.
+
+p
+  | Ver también 
+  a(href="https://www.pychess.org/variant/minixiangqi") Minixiangqi
+  | & nbsp;en pychess-variants.
diff --git a/client/src/translations/rules/Minixiangqi/fr.pug b/client/src/translations/rules/Minixiangqi/fr.pug
new file mode 100644
index 00000000..b3ab2a60
--- /dev/null
+++ b/client/src/translations/rules/Minixiangqi/fr.pug
@@ -0,0 +1,22 @@
+p.boxed Xiangqi sur un plateau 7 x 7.
+
+figure.diagram-container
+  .diagram
+    | fen:rcnkncr/p1ppp1p/7/7/7/P1PPP1P/RCNKNCR:
+  figcaption Position initiale.
+
+p.
+  Cette variante correspond au Xiangqi sur un échiquier 7x7.
+  Ce jeu a été inventé (ou redécouvert) en 1973 par Shigenobu Kusumoto
+  d'Osaka, Japon.
+
+p
+  | Les règles sont les mêmes qu'au 
+  a(href="/#/variants/Xiangqi") Xiangqi
+  | . Contrairement au Xiangqi standard, il n'y a ni éléphant ni conseiller.
+  | Les pions ont toujours l'option de se déplacer létaralement.
+
+p
+  | Voir aussi 
+  a(href="https://www.pychess.org/variant/minixiangqi") Minixiangqi
+  | &nbsp;sur pychess-variants.
diff --git a/client/src/variants/Minishogi.js b/client/src/variants/Minishogi.js
index d7bc0d71..15148296 100644
--- a/client/src/variants/Minishogi.js
+++ b/client/src/variants/Minishogi.js
@@ -1,5 +1,5 @@
 import { ChessRules, PiPo, Move } from "@/base_rules";
-import { ShogiRules } from "@/variants/Shogi";
+import { ShogiRules } from "@/variants/Shogi"
 
 export class MinishogiRules extends ShogiRules {
 
diff --git a/client/src/variants/Minixiangqi.js b/client/src/variants/Minixiangqi.js
new file mode 100644
index 00000000..c027aedf
--- /dev/null
+++ b/client/src/variants/Minixiangqi.js
@@ -0,0 +1,93 @@
+import { ChessRules, PiPo, Move } from "@/base_rules";
+import { XiangqiRules } from "@/variants/Xiangqi"
+
+export class MinixiangqiRules extends XiangqiRules {
+
+  static get Lines() {
+    let lines = [];
+    // Draw all inter-squares lines, shifted:
+    for (let i = 0; i < V.size.x; i++)
+      lines.push([[i+0.5, 0.5], [i+0.5, V.size.y-0.5]]);
+    for (let j = 0; j < V.size.y; j++)
+      lines.push([[0.5, j+0.5], [V.size.x-0.5, j+0.5]]);
+    // Add palaces:
+    lines.push([[0.5, 2.5], [2.5, 4.5]]);
+    lines.push([[0.5, 4.5], [2.5, 2.5]]);
+    lines.push([[4.5, 2.5], [6.5, 4.5]]);
+    lines.push([[4.5, 4.5], [6.5, 2.5]]);
+    return lines;
+  }
+
+  // No elephants or advisors
+  static get PIECES() {
+    return [V.PAWN, V.ROOK, V.KNIGHT, V.KING, V.CANNON];
+  }
+
+  getPpath(b) {
+    return "Xiangqi/" + b;
+  }
+
+  static get size() {
+    return { x: 7, y: 7};
+  }
+
+  getPotentialMovesFrom(sq) {
+    switch (this.getPiece(sq[0], sq[1])) {
+      case V.PAWN: return this.getPotentialPawnMoves(sq);
+      case V.ROOK: return super.getPotentialRookMoves(sq);
+      case V.KNIGHT: return super.getPotentialKnightMoves(sq);
+      case V.KING: return super.getPotentialKingMoves(sq);
+      case V.CANNON: return super.getPotentialCannonMoves(sq);
+    }
+    return []; //never reached
+  }
+
+  getPotentialPawnMoves([x, y]) {
+    const c = this.getColor(x, y);
+    const shiftX = (c == 'w' ? -1 : 1);
+    const lastRank = (c == 'w' && x == 0 || c == 'b' && x == 6);
+    let steps = [];
+    if (!lastRank) steps.push([shiftX, 0]);
+    if (y > 0) steps.push([0, -1]);
+    if (y < 9) steps.push([0, 1]);
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  insidePalace(x, y, c) {
+    return (
+      (y >= 2 && y <= 4) &&
+      (
+        (c == 'w' && x >= 4) ||
+        (c == 'b' && x <= 2)
+      )
+    );
+  }
+
+  static get VALUES() {
+    return {
+      p: 2,
+      r: 9,
+      n: 4,
+      c: 4.5,
+      k: 1000
+    };
+  }
+
+  // Back to ChessRules method:
+  evalPosition() {
+    let evaluation = 0;
+    for (let i = 0; i < V.size.x; i++) {
+      for (let j = 0; j < V.size.y; j++) {
+        if (this.board[i][j] != V.EMPTY)
+          evaluation += (c == 'w' ? 1 : -1) * V.VALUES[this.getPiece(i, j)];
+      }
+    }
+    return evaluation;
+  }
+
+  // Also no randomization here
+  static GenRandInitFen() {
+    return "rcnkncr/p1ppp1p/7/7/7/P1PPP1P/RCNKNCR w 0";
+  }
+
+};
diff --git a/server/db/populate.sql b/server/db/populate.sql
index b0596058..18d92693 100644
--- a/server/db/populate.sql
+++ b/server/db/populate.sql
@@ -76,6 +76,7 @@ insert or ignore into Variants (name, description) values
   ('Makruk', 'Thai Chess'),
   ('Maxima', 'Occupy the enemy palace'),
   ('Minishogi', 'Shogi 5 x 5'),
+  ('Minixiangqi', 'Xiangqi 7 x 7'),
   ('Monochrome', 'All of the same color'),
   ('Monster', 'White move twice'),
   ('Omega', 'A wizard in the corner'),
-- 
2.44.0