From 236485b53993f2adfd588022e2899a39491fc825 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sat, 18 Apr 2020 04:51:07 +0200
Subject: [PATCH] Add Koth (experimental)

---
 TODO                                      |  6 ---
 client/src/components/MoveList.vue        |  2 +-
 client/src/translations/en.js             |  1 +
 client/src/translations/es.js             |  1 +
 client/src/translations/fr.js             |  1 +
 client/src/translations/rules/Koth/en.pug | 21 ++++++++++
 client/src/translations/rules/Koth/es.pug | 22 +++++++++++
 client/src/translations/rules/Koth/fr.pug | 22 +++++++++++
 client/src/variants/Koth.js               | 48 +++++++++++++++++++++++
 server/db/populate.sql                    |  1 +
 10 files changed, 118 insertions(+), 7 deletions(-)
 create mode 100644 client/src/translations/rules/Koth/en.pug
 create mode 100644 client/src/translations/rules/Koth/es.pug
 create mode 100644 client/src/translations/rules/Koth/fr.pug
 create mode 100644 client/src/variants/Koth.js

diff --git a/TODO b/TODO
index 97072023..c1197fa8 100644
--- a/TODO
+++ b/TODO
@@ -5,10 +5,6 @@ https://www.chessvariants.com/d.betza/chessvar/trapdoor.html
 https://www.chessvariants.com/crossover.dir/koopachess.html
 --> Can a stunned piece capture? Maybe not. ...recover? After 5 moves? Never?
 
-Diamond Chess [Rynd] (J. A.
-Porterfield Rynd, 1886)  --> Berolina2 ?
-https://www.chessvariants.com/rules/diamond-chess
-
 Bicolour Chess (Gabriel Authier, 1958). v1 et v2 : (Roméo Bédoni, 1958) 
 Kings are subject to check and checkmate by
 own as well as opponent’s pieces. The Q and
@@ -17,8 +13,6 @@ QN are interchanged in the array
 v2: y but a player may capture his
 own men (TODO: only v2?)
 
-Koth : king of the hill, king cannot move into check, giving check is forbidden (no checkmate).
-
 Berolina Grid Chess, also known as
 Gridolina (originator not noted). A
 combination of Berolina and Grid Chess.
diff --git a/client/src/components/MoveList.vue b/client/src/components/MoveList.vue
index d47a1a4a..1f94d638 100644
--- a/client/src/components/MoveList.vue
+++ b/client/src/components/MoveList.vue
@@ -241,7 +241,7 @@ span#rulesBtn
 button
   margin: 0
   &.active
-    background-color: #50E99A
+    background-color: #48C9B0
 
 #aboveMoves button
   padding-bottom: 5px
diff --git a/client/src/translations/en.js b/client/src/translations/en.js
index e3fb36df..375bb4d4 100644
--- a/client/src/translations/en.js
+++ b/client/src/translations/en.js
@@ -190,6 +190,7 @@ export const translations = {
   "Japanese Chess": "Japanese Chess",
   "Keep antiking in check (v1)": "Keep antiking in check (v1)",
   "Keep antiking in check (v2)": "Keep antiking in check (v2)",
+  "King of the Hill": "King of the Hill",
   "Kings cross the 8x8 board": "Kings cross the 8x8 board",
   "Kings cross the 11x11 board": "Kings cross the 11x11 board",
   "Landing on the board": "Landing on the board",
diff --git a/client/src/translations/es.js b/client/src/translations/es.js
index 556072bd..932bc2b5 100644
--- a/client/src/translations/es.js
+++ b/client/src/translations/es.js
@@ -190,6 +190,7 @@ export const translations = {
   "Japanese Chess": "Ajedrez japonés",
   "Keep antiking in check (v1)": "Mantener el antirey en jaque (v1)",
   "Keep antiking in check (v2)": "Mantener el antirey en jaque (v2)",
+  "King of the Hill": "Rey de la Colina",
   "Kings cross the 8x8 board": "Los reyes cruzan el 8x8 tablero",
   "Kings cross the 11x11 board": "Los reyes cruzan el 11x11 tablero",
   "Landing on the board": "Aterrizando en el tablero",
diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js
index eb345b8e..9243c987 100644
--- a/client/src/translations/fr.js
+++ b/client/src/translations/fr.js
@@ -190,6 +190,7 @@ export const translations = {
   "Japanese Chess": "Échecs japonais",
   "Keep antiking in check (v1)": "Gardez l'antiroi en échec (v1)",
   "Keep antiking in check (v2)": "Gardez l'antiroi en échec (v2)",
+  "King of the Hill": "Roi de la Colline",
   "Kings cross the 8x8 board": "Les rois traversent l'échiquier 8x8",
   "Kings cross the 11x11 board": "Les rois traversent l'échiquier 11x11",
   "Landing on the board": "Débarquement sur l'échiquier",
diff --git a/client/src/translations/rules/Koth/en.pug b/client/src/translations/rules/Koth/en.pug
new file mode 100644
index 00000000..422e8faf
--- /dev/null
+++ b/client/src/translations/rules/Koth/en.pug
@@ -0,0 +1,21 @@
+p.boxed
+  | Bring the king to the middle to win. Giving check is forbidden.
+
+p Orthodox rules apply, with two changes:
+ul
+  li.
+    The goal is to bring the king on one of the central squares
+    d4, e4, d5 or e5. "Koth" stands indeed for "King of the Hill".
+  li Giving check is forbidden (thus no checkmate is possible).
+
+figure.diagram-container
+  .diagram
+    | fen:k4r2/1p2p3/2P4p/5pp1/p2B4/5KP1/PPQ1P2P/R7:
+  figcaption White can win in two moves: 1.Qxf5 and 2.Ke4#
+
+h3 Source
+
+p
+  | Modified from Koth as playable 
+  a(href="https://lichess.org/variant/kingOfTheHill") on lichess
+  | . Experimental change: I'd like to see how it plays without checks :)
diff --git a/client/src/translations/rules/Koth/es.pug b/client/src/translations/rules/Koth/es.pug
new file mode 100644
index 00000000..5e84f938
--- /dev/null
+++ b/client/src/translations/rules/Koth/es.pug
@@ -0,0 +1,22 @@
+p.boxed
+  | Lleva el rey al centro para ganar. Prohibido de dar jaque.
+
+p Se aplican las reglas ortodoxas, con dos cambios:
+ul
+  li.
+    El objetivo es llevar el rey a uno de los espacios centrales d4, e4, d5
+    o e5. "Koth" es de hecho la abreviatura inglesa para "Rey de la Colina".
+  li Los jaques son prohibidos (por lo tanto, el jaque mate es imposible).
+
+figure.diagram-container
+  .diagram
+    | fen:k4r2/1p2p3/2P4p/5pp1/p2B4/5KP1/PPQ1P2P/R7:
+  figcaption Las blancas pueden ganar en dos movimientos: 1.Qxf5 y 2.Ke4#
+
+h3 Fuente
+
+p
+  | Cambiado de la variante Koth jugable 
+  a(href="https://lichess.org/variant/kingOfTheHill") en lichess
+  | . Cambio experimental: me gustaría ver los efectos de la condición que
+  | previene jaques :)
diff --git a/client/src/translations/rules/Koth/fr.pug b/client/src/translations/rules/Koth/fr.pug
new file mode 100644
index 00000000..79c0272b
--- /dev/null
+++ b/client/src/translations/rules/Koth/fr.pug
@@ -0,0 +1,22 @@
+p.boxed
+  | Amenez le roi au centre pour gagner. Interdit de donner échec.
+
+p Les règles orthodoxes s'appliquent, avec deux changements :
+ul
+  li.
+    L'objectif est d'amener le roi sur l'une des cases centrales d4, e4, d5
+    ou e5. "Koth" est en effet l'abbréviation anglaise de "Roi de la Colline".
+  li Les échecs sont interdits (l'échec et mat est donc imppossible).
+
+figure.diagram-container
+  .diagram
+    | fen:k4r2/1p2p3/2P4p/5pp1/p2B4/5KP1/PPQ1P2P/R7:
+  figcaption Les blancs peuvent gagner en deux coups : 1.Qxf5 et 2.Ke4#
+
+h3 Source
+
+p
+  | Modifié depuis la variante Koth jouable 
+  a(href="https://lichess.org/variant/kingOfTheHill") sur lichess
+  | . Changement expérimental : j'aimerais voir les effets de la condition
+  | empêchant les échecs :)
diff --git a/client/src/variants/Koth.js b/client/src/variants/Koth.js
new file mode 100644
index 00000000..e286862d
--- /dev/null
+++ b/client/src/variants/Koth.js
@@ -0,0 +1,48 @@
+import { ChessRules } from "@/base_rules";
+
+export class KothRules extends ChessRules {
+  filterValid(moves) {
+    if (moves.length == 0) return [];
+    const color = this.turn;
+    const oppCol = V.GetOppCol(color);
+    return moves.filter(m => {
+      this.play(m);
+      // Giving check is forbidden as well:
+      const res = !this.underCheck(color) && !this.underCheck(oppCol);
+      this.undo(m);
+      return res;
+    });
+  }
+
+  getCurrentScore() {
+    // Turn has changed:
+    const color = V.GetOppCol(this.turn);
+    if (
+      [3,4].includes(this.kingPos[color][0]) &&
+      [3,4].includes(this.kingPos[color][1])
+    ) {
+      // The middle is reached!
+      return color == "w" ? "1-0" : "0-1";
+    }
+    if (this.atLeastOneMove()) return "*";
+    // Stalemate (will probably never happen)
+    return "1/2";
+  }
+
+  evalPosition() {
+    // Count material:
+    let evaluation = super.evalPosition();
+    // Ponder with king position:
+    return (
+      evaluation/5 +
+      (
+        Math.abs(this.kingPos["w"][0] - 3.5) +
+        Math.abs(this.kingPos["w"][1] - 3.5)
+      ) / 2 -
+      (
+        Math.abs(this.kingPos["b"][0] - 3.5) +
+        Math.abs(this.kingPos["b"][1] - 3.5)
+      ) / 2
+    );
+  }
+};
diff --git a/server/db/populate.sql b/server/db/populate.sql
index 21f7c7a8..51dae3fe 100644
--- a/server/db/populate.sql
+++ b/server/db/populate.sql
@@ -48,6 +48,7 @@ insert or ignore into Variants (name, description) values
   ('Knightmate', 'Mate the knight'),
   ('Knightrelay1', 'Move like a knight (v1)'),
   ('Knightrelay2', 'Move like a knight (v2)'),
+  ('Koth', 'King of the Hill'),
   ('Losers', 'Get strong at self-mate'),
   ('Magnetic', 'Laws of attraction'),
   ('Makruk', 'Thai Chess'),
-- 
2.44.0