From 5c1c7bcec764d94b0469ab4d7d0777ce67e05ae3 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Thu, 5 Oct 2023 16:25:45 +0200
Subject: [PATCH] Prepare Coregal variant

---
 base_rules.js                        |   2 +-
 pieces/Coregal/black_royal_queen.svg |   8 ++
 pieces/Coregal/white_royal_queen.svg |  19 +++++
 variants/Coregal/Coregal.js          | 121 ---------------------------
 variants/Coregal/class.js            |  67 +++++++++++++++
 variants/Coregal/rules.html          |   6 ++
 variants/Coregal/style.css           |   8 ++
 7 files changed, 109 insertions(+), 122 deletions(-)
 create mode 100644 pieces/Coregal/black_royal_queen.svg
 create mode 100644 pieces/Coregal/white_royal_queen.svg
 delete mode 100644 variants/Coregal/Coregal.js
 create mode 100644 variants/Coregal/class.js
 create mode 100644 variants/Coregal/rules.html
 create mode 100644 variants/Coregal/style.css

diff --git a/base_rules.js b/base_rules.js
index 0b71cf4..6078da8 100644
--- a/base_rules.js
+++ b/base_rules.js
@@ -235,7 +235,7 @@ export default class ChessRules {
         randomness: this.options["randomness"],
         between: [{p1: 'k', p2: 'r'}],
         diffCol: ['b'],
-        flags: ['r']
+        flags: ['r', 'k']
       }
     );
     return {
diff --git a/pieces/Coregal/black_royal_queen.svg b/pieces/Coregal/black_royal_queen.svg
new file mode 100644
index 0000000..49bfbe3
--- /dev/null
+++ b/pieces/Coregal/black_royal_queen.svg
@@ -0,0 +1,8 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1588 793q-83 30-233 49t-333 20q-178 0-326-18t-233-49l50-91q84 25 218 36t293 11q159 0 294-11t219-37l51 90zm226 668q-57 0-97 39t-40 97q0 56 40 96t97 41q56 0 96-40t40-97q0-57-40-96t-96-40zm-1578 0q-57 0-96 39t-40 97q0 56 39 96t97 41q57 0 97-40t40-97q0-57-40-96t-97-40zm1208 110q-57 0-96 39t-40 97q0 56 39 96t97 40q57 0 97-40t40-96q0-57-40-96t-97-40zm-840 0q-57 0-97 39t-40 97q0 56 40 96t97 40q56 0 96-40t40-96q0-57-40-96t-96-40zm1036-1288q-49-43-220-72t-394-29q-227 0-399 30t-217 75l63 240-28 157-88 153-85 622 49 19 274-462 6 550 68 12 209-553 112 595h69l112-593 207 551 69-12 6-550 275 463 47-22-83-619-89-153-28-159 65-243zm-96 32l-30 118q-195 45-490 45-292 0-488-45l-32-119q190 58 521 58 159 0 295-16t224-41zm-26 299q-184 51-490 51-308 0-496-52l15-101q189 49 481 49 291 0 474-48l16 101zm-494 1007q-57 0-96 40t-40 97q0 56 39 96t97 40q56 0 96-40t41-96q0-57-40-97t-97-40z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1588 1255q-83-30-233-49t-333-20q-178 0-326 18t-233 49l50 91q84-25 218-36t293-11 294 11 219 37l51-90z" display="block"/>
+  <path style="color:black;" d="m1544 1733-30-118q-195-45-490-45-292 0-488 45l-32 119q190-58 521-58 159 0 295 16t224 41z" display="block"/>
+  <path style="color:black;" d="m1518 1434q-184-51-490-51-308 0-496 52l15 101q189-49 481-49 291 0 474 48l16-101z" display="block"/>
+ </g>
+</svg>
diff --git a/pieces/Coregal/white_royal_queen.svg b/pieces/Coregal/white_royal_queen.svg
new file mode 100644
index 0000000..b98b76f
--- /dev/null
+++ b/pieces/Coregal/white_royal_queen.svg
@@ -0,0 +1,19 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1024 1621q-57 0-96 40t-40 97q0 56 39 96t97 40q56 0 96-40t41-96q0-57-40-97t-97-40zm0 70q67 0 67 67 0 66-67 66-66 0-66-66 0-67 66-67zm509-1007q-193 49-505 49-320 0-511-50l15-96q195 46 496 46 299 0 488-45l17 96zm25 60 65 115q-48-19-98-19-134 0-214 109-60-50-134-50-96 0-153 75-64-70-153-70-72 0-132 49-84-107-217-107-51 0-101 19l70-120q194 56 533 56 345 0 534-57zm-448 239-85 489-85-483q3 2 14 10 23 45 70 45 51 0 66-45 6-6 20-16zm277-19v463l-165-454q19 7 32 18 20 25 54 25 40 0 64-35 3-4 7-8t8-9zm-562 14-164 449v-457q3 4 9 10 20 42 66 42 38 0 62-32 27-12 27-12zm-254-56-215 371 55-338q57-40 111-40 21 0 49 7zm903-5q23-7 51-7 61 0 114 38l55 346-220-377zm60-506-30 113q-196 43-480 43-281 0-479-43l-31-114q186 56 511 56 317 0 509-55zm106-128q-49-43-220-72t-394-29q-227 0-399 30t-217 75l63 240-28 157-88 153-85 622 49 19 274-462 6 550 68 12 209-553 112 595h69l112-593 207 551 69-12 6-550 275 463 47-22-83-619-89-153-28-159 65-243zm-81 36q-183 76-531 76-355 0-537-78 175-69 534-69 172 0 314 19t220 52zm-955 1252q-57 0-97 39t-40 97q0 56 40 96t97 40q56 0 96-40t40-96q0-57-40-96t-96-40zm0 70q66 0 66 66t-66 66q-67 0-67-66t67-66zm840 0q67 0 67 66t-67 66q-66 0-66-66t66-66zm0-70q-57 0-96 39t-40 97q0 56 39 96t97 40q57 0 97-40t40-96q0-57-40-96t-97-40zm-1208-110q-57 0-96 39t-40 97q0 56 39 96t97 41q57 0 97-40t40-97-40-96-97-40zm0 70q67 0 67 66 0 67-67 67-66 0-66-67 0-66 66-66zm1578 0q66 0 66 66 0 67-66 67-67 0-67-67 0-66 67-66zm0-70q-57 0-97 39t-40 97q0 56 40 96t97 41q56 0 96-40t40-97-40-96-96-40z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1024 357q67 0 67-67 0-66-67-66-66 0-66 66 0 67 66 67z" display="block"/>
+  <path style="color:black;" d="m1533 1364q-193-49-505-49-320 0-511 50l15 96q195-46 496-46 299 0 488 45l17-96z" display="block"/>
+  <path style="color:black;" d="m1558 1304 65-115q-48 19-98 19-134 0-214-109-60 50-134 50-96 0-153-75-64 70-153 70-72 0-132-49-84 107-217 107-51 0-101-19l70 120q194-56 533-56 345 0 534 57z" display="block"/>
+  <path style="color:black;" d="m1110 1065-85-489-85 483q3-2 14-10 23-45 70-45 51 0 66 45 6 6 20 16z" display="block"/>
+  <path style="color:black;" d="m1387 1084v-463l-165 454q19-7 32-18 20-25 54-25 40 0 64 35 3 4 7 8t8 9z" display="block"/>
+  <path style="color:black;" d="m825 1070-164-449v457q3-4 9-10 20-42 66-42 38 0 62 32 27 12 27 12z" display="block"/>
+  <path style="color:black;" d="m571 1126-215-371 55 338q57 40 111 40 21 0 49-7z" display="block"/>
+  <path style="color:black;" d="m1474 1131q23 7 51 7 61 0 114-38l55-346-220 377z" display="block"/>
+  <path style="color:black;" d="m1534 1637-30-113q-196-43-480-43-281 0-479 43l-31 114q186-56 511-56 317 0 509 55z" display="block"/>
+  <path style="color:black;" d="m1559 1729q-183-76-531-76-355 0-537 78 175 69 534 69 172 0 314-19t220-52z" display="block"/>
+  <path style="color:black;" d="m604 407q66 0 66-66t-66-66q-67 0-67 66t67 66z" display="block"/>
+  <path style="color:black;" d="m1444 407q67 0 67-66t-67-66q-66 0-66 66t66 66z" display="block"/>
+  <path style="color:black;" d="m236 517q67 0 67-66 0-67-67-67-66 0-66 67 0 66 66 66z" display="block"/>
+  <path style="color:black;" d="m1814 517q66 0 66-66 0-67-66-67-67 0-67 67 0 66 67 66z" display="block"/>
+ </g>
+</svg>
diff --git a/variants/Coregal/Coregal.js b/variants/Coregal/Coregal.js
deleted file mode 100644
index e12a748..0000000
--- a/variants/Coregal/Coregal.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import { ChessRules, Move, PiPo } from "@/base_rules";
-import { ArrayFun } from "@/utils/array";
-import { randInt, sample } from "@/utils/alea";
-
-export class CoregalRules extends ChessRules {
-
-// TODO: special symbol (l) for royal queen...
-
-  getPPpath(m) {
-    if (
-      m.vanish.length == 2 &&
-      m.appear.length == 2 &&
-      m.vanish[0].p == V.QUEEN
-    ) {
-      // Large castle: show castle symbol
-      return "Coregal/castle";
-    }
-    return super.getPPpath(m);
-  }
-
-  genRandInitBaseFen() {
-    const s = FenUtil.setupPieces(
-      ['r', 'n', 'b', 'l', 'k', 'b', 'n', 'r'],
-      {
-        randomness: this.options["randomness"],
-        between: [{p1: 'k', p2: 'r'}, {p1: 'l', p2: 'r'}],
-        diffCol: ['b'],
-        flags: ['r', 'k', 'l']
-      }
-    );
-    return {
-      fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
-           s.w.join("").toUpperCase(),
-      o: {flags: s.flags}
-    };
-  }
-
-  pieces() {
-    let res = super.pieces();
-    res['l'] = {...};
-    return res;
-  }
-
-  setFlags(fenflags) {
-    // white pieces positions, then black pieces positions
-    this.castleFlags = { w: [...Array(4)], b: [...Array(4)] };
-    for (let i = 0; i < 8; i++) {
-      this.castleFlags[i < 4 ? "w" : "b"][i % 4] =
-        parseInt(fenflags.charAt(i), 10);
-    }
-  }
-
-  getPotentialQueenMoves([x, y]) {
-    let moves = super.getPotentialQueenMoves([x, y]);
-    const c = this.getColor(x, y);
-    if (this.castleFlags[c].slice(1, 3).includes(y))
-      moves = moves.concat(this.getCastleMoves([x, y]));
-    return moves;
-  }
-
-  getPotentialKingMoves([x, y]) {
-    let moves = this.getSlideNJumpMoves(
-      [x, y], V.steps[V.ROOK].concat(V.steps[V.BISHOP]), 1);
-    const c = this.getColor(x, y);
-    if (this.castleFlags[c].slice(1, 3).includes(y))
-      moves = moves.concat(this.getCastleMoves([x, y]));
-    return moves;
-  }
-
-  getCastleMoves([x, y]) {
-    // Relative position of the selected piece: left or right ?
-    // If left: small castle left, large castle right.
-    // If right: usual situation.
-    const c = this.getColor(x, y);
-    const relPos = (this.castleFlags[c][1] == y ? "left" : "right");
-
-    const finalSquares = [
-      relPos == "left" ? [1, 2] : [2, 3],
-      relPos == "right" ? [6, 5] : [5, 4]
-    ];
-    const saveFlags = JSON.stringify(this.castleFlags[c]);
-    // Alter flags to follow base_rules semantic
-    this.castleFlags[c] = [0, 3].map(i => this.castleFlags[c][i]);
-    const moves = super.getCastleMoves([x, y], finalSquares);
-    this.castleFlags[c] = JSON.parse(saveFlags);
-    return moves;
-  }
-
-  // "twoKings" arg for the similar Twokings variant.
-  updateCastleFlags(move, piece, twoKings) {
-    const c = V.GetOppCol(this.turn);
-    const firstRank = (c == "w" ? V.size.x - 1 : 0);
-    // Update castling flags if castling pieces moved or were captured
-    const oppCol = V.GetOppCol(c);
-    const oppFirstRank = V.size.x - 1 - firstRank;
-    if (move.start.x == firstRank) {
-      if (piece == V.KING || (!twoKings && piece == V.QUEEN)) {
-        if (this.castleFlags[c][1] == move.start.y)
-          this.castleFlags[c][1] = 8;
-        else if (this.castleFlags[c][2] == move.start.y)
-          this.castleFlags[c][2] = 8;
-        // Else: the flag is already turned off
-      }
-    }
-    else if (
-      move.start.x == firstRank && //our rook moves?
-      [this.castleFlags[c][0], this.castleFlags[c][3]].includes(move.start.y)
-    ) {
-      const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 3);
-      this.castleFlags[c][flagIdx] = 8;
-    } else if (
-      move.end.x == oppFirstRank && //we took opponent rook?
-      [this.castleFlags[oppCol][0], this.castleFlags[oppCol][3]]
-        .includes(move.end.y)
-    ) {
-      const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 3);
-      this.castleFlags[oppCol][flagIdx] = 8;
-    }
-  }
-
-};
diff --git a/variants/Coregal/class.js b/variants/Coregal/class.js
new file mode 100644
index 0000000..b563fec
--- /dev/null
+++ b/variants/Coregal/class.js
@@ -0,0 +1,67 @@
+import { ChessRules, Move, PiPo } from "@/base_rules";
+import { ArrayFun } from "@/utils/array";
+import { randInt, sample } from "@/utils/alea";
+
+export class CoregalRules extends ChessRules {
+
+//TODO: CSS royal queen symbol
+
+  genRandInitBaseFen() {
+    const s = FenUtil.setupPieces(
+      ['r', 'n', 'b', 'l', 'k', 'b', 'n', 'r'],
+      {
+        randomness: this.options["randomness"],
+        between: [{p1: 'k', p2: 'r'}, {p1: 'l', p2: 'r'}],
+        diffCol: ['b'],
+        flags: ['r', 'k', 'l'] //TODO: add 'k' to all 'flags' calls ??!
+      }
+    );
+    return {
+      fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
+           s.w.join("").toUpperCase(),
+      o: {flags: s.flags}
+    };
+  }
+
+  pieces() {
+    let res = super.pieces();
+    res['l'] = JSON.parse(JSON.stringify(res['q']));
+    res['l']["class"] = "royal_queen";
+    return res;
+  }
+
+  setFlags(fenflags) {
+    // white pieces positions, then black pieces positions
+    this.castleFlags = { w: [...Array(4)], b: [...Array(4)] };
+    for (let i = 0; i < 8; i++) {
+      this.castleFlags[i < 4 ? "w" : "b"][i % 4] =
+        parseInt(fenflags.charAt(i), 10);
+    }
+  }
+
+  isKing(x, y, p) {
+    if (!p)
+      p = this.getPiece(x, y);
+    ['k', 'l'].includes(p); //no cannibal mode
+  }
+
+  getCastleMoves([x, y]) {
+    // Relative position of the selected piece: left or right ?
+    // If left: small castle left, large castle right.
+    // If right: usual situation.
+    const c = this.getColor(x, y);
+    const relPos = (this.castleFlags[c][1] == y ? "left" : "right");
+
+    const finalSquares = [
+      relPos == "left" ? [1, 2] : [2, 3],
+      relPos == "right" ? [6, 5] : [5, 4]
+    ];
+    const saveFlags = JSON.stringify(this.castleFlags[c]);
+    // Alter flags to follow base_rules semantic
+    this.castleFlags[c] = [0, 3].map(i => this.castleFlags[c][i]);
+    const moves = super.getCastleMoves([x, y], finalSquares);
+    this.castleFlags[c] = JSON.parse(saveFlags);
+    return moves;
+  }
+
+};
diff --git a/variants/Coregal/rules.html b/variants/Coregal/rules.html
new file mode 100644
index 0000000..8b5ee63
--- /dev/null
+++ b/variants/Coregal/rules.html
@@ -0,0 +1,6 @@
+<p>
+  The queen is royal too: she cannot move or remain into check,
+  and can be checkmated. Qhe has the right to castle with either rook.
+</p>
+
+<p class="author">Vernon R. Parton (1970).</p>
diff --git a/variants/Coregal/style.css b/variants/Coregal/style.css
new file mode 100644
index 0000000..b0046d0
--- /dev/null
+++ b/variants/Coregal/style.css
@@ -0,0 +1,8 @@
+@import url("/base_pieces.css");
+
+piece.black.royal_queen {
+  background-image: url('/pieces/Coregal/black_royal_queen.svg');
+}
+piece.white.royal_queen {
+  background-image: url('/pieces/Coregal/white_royal_queen.svg');
+}
-- 
2.44.0