From 5269839f65908a0782db512f498e2d55662bee9f Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sun, 23 Jul 2023 19:32:36 +0200
Subject: [PATCH] Clorange: almost functional draft (promotions, capture
 non-violent...)

---
 variants.js                  |  2 +-
 variants/Clorange/class.js   | 58 +++++++++++++++++++++---------------
 variants/Clorange/rules.html |  8 +++++
 variants/Clorange/style.css  | 33 ++++++++++++++++++++
 4 files changed, 76 insertions(+), 25 deletions(-)
 create mode 100644 variants/Clorange/rules.html
 create mode 100644 variants/Clorange/style.css

diff --git a/variants.js b/variants.js
index c20f800..1b398aa 100644
--- a/variants.js
+++ b/variants.js
@@ -30,7 +30,7 @@ const variants = [
   {name: 'Checkless', desc: 'No-check mode'},
   {name: 'Chess960', disp: "Chess 960", desc: "Standard rules"},
   {name: 'Circular', desc: 'Run forward'},
-//  {name: 'Clorange', desc: 'A Clockwork Orange', disp: 'Clockwork Orange'},
+  {name: 'Clorange', desc: 'A Clockwork Orange', disp: 'Clockwork Orange'},
 //  {name: 'Convert', desc: 'Convert enemy pieces'},
 //  {name: 'Copycat', desc: 'Borrow powers'},
 //  {name: 'Coregal', desc: 'Two royal pieces'},
diff --git a/variants/Clorange/class.js b/variants/Clorange/class.js
index 38cb958..01d7189 100644
--- a/variants/Clorange/class.js
+++ b/variants/Clorange/class.js
@@ -2,7 +2,13 @@ import ChessRules from "/base_rules.js";
 
 export default class ClorangeRules extends ChessRules {
 
-  // TODO: options : disable teleport/recycle at least ?
+  static get Options() {
+    return {
+      select: C.Options.select,
+      styles:
+        C.Options.styles.filter(s => !["crazyhouse","recycle"].includes(s))
+    };
+  }
 
   get hasReserve() {
     return true;
@@ -23,44 +29,48 @@ export default class ClorangeRules extends ChessRules {
     res['o'] = {"class": "nv-knight", moveas: "n"};
     res['c'] = {"class": "nv-bishop", moveas: "b"};
     res['t'] = {"class": "nv-queen", moveas: "q"};
+    return res;
   }
 
-  setOtherVariables(fen) {
-    super.setOtherVariables(fen,
-      ['p', 'r', 'n', 'b', 'q', 's', 'u', 'o', 'c', 't']);
+  static get V_PIECES() {
+    return ['p', 'r', 'n', 'b', 'q'];
+  }
+  static get NV_PIECES() {
+    return ['s', 'u', 'o', 'c', 't'];
   }
 
-  postProcessPotentialMoves(moves) {
-    // Remove captures for non-violent pieces:
-    return super.postProcessPotentialMoves(moves).filter(m => {
-      return (
-        m.vanish.length != 2 ||
-        m.appear.length != 1 ||
-        ['p', 'r', 'n', 'b', 'q'].includes(m.vanish[0].p)
-      );
-    });
+  setOtherVariables(fen) {
+    super.setOtherVariables(fen, V.V_PIECES.concat(V.NV_PIECES));
   }
 
+  // Forbid non-violent pieces to capture
   canTake([x1, y1], [x2, y2]) {
     return (
       this.getColor(x1, y1) !== this.getColor(x2, y2) &&
-      ['p', 'r', 'n', 'b', 'q', 'k'].includes(this.getPiece(x1, y1))
+      (['k'].concat(V.V_PIECES)).includes(this.getPiece(x1, y1))
     );
   }
 
   prePlay(move) {
     super.prePlay(move);
     // No crazyhouse or recycle, so the last call didn't update reserve:
-    if (move.vanish.length == 2 && move.appear.length == 1) {
-      // Capture: update reserves
-      this.Reserve[move.vanish
-      const pIdx = ['p', 'r', 'n', 'b', 'q'].indexOf(move.vanish[1].p);
-      // TODO
-      if normal
-          ? ChessRules.PIECES.findIndex(p => p == move.vanish[1].p)
-          : V.NON_VIOLENT.findIndex(p => p == move.vanish[1].p);
-      const rPiece = (normal ? V.NON_VIOLENT : ChessRules.PIECES)[pIdx];
-      this.reserve[move.vanish[1].c][rPiece]++;
+    if (
+      (move.vanish.length == 2 && move.appear.length == 1) ||
+      move.vanish.length == 0 //drop
+    ) {
+      const trPiece =
+        (move.vanish.length > 0 ? move.vanish[1].p : move.appear[0].p);
+      const normal = V.V_PIECES.includes(trPiece);
+      const pIdx = (normal ? V.V_PIECES : V.NV_PIECES).indexOf(trPiece);
+      const resPiece = (normal ? V.NV_PIECES : V.V_PIECES)[pIdx];
+      if (move.vanish.length > 0) {
+        super.updateReserve(C.GetOppTurn(this.turn), resPiece,
+          this.reserve[C.GetOppTurn(this.turn)][resPiece] + 1);
+      }
+      else {
+        super.updateReserve(this.turn, resPiece,
+          this.reserve[this.turn][resPiece] - 1);
+      }
     }
   }
 
diff --git a/variants/Clorange/rules.html b/variants/Clorange/rules.html
new file mode 100644
index 0000000..f10e7f6
--- /dev/null
+++ b/variants/Clorange/rules.html
@@ -0,0 +1,8 @@
+<p>Captured pieces can be landed later in a non-capturing form;<br>
+they regain their ability to capture when captured again.</p>
+
+<a href="https://www.chessvariants.com/other.dir/clockworkorange.html">
+  chessvariants page.
+</a>
+
+<p class="author">Fergus Duniho (1999).</p>
diff --git a/variants/Clorange/style.css b/variants/Clorange/style.css
new file mode 100644
index 0000000..98324a9
--- /dev/null
+++ b/variants/Clorange/style.css
@@ -0,0 +1,33 @@
+@import url("/base_pieces.css");
+
+piece.white.nv-pawn {
+  background-image: url('/pieces/yellow_pawn.svg');
+}
+piece.white.nv-rook {
+  background-image: url('/pieces/yellow_rook.svg');
+}
+piece.white.nv-knight {
+  background-image: url('/pieces/yellow_knight.svg');
+}
+piece.white.nv-bishop {
+  background-image: url('/pieces/yellow_bishop.svg');
+}
+piece.white.nv-queen {
+  background-image: url('/pieces/yellow_queen.svg');
+}
+
+piece.black.nv-pawn {
+  background-image: url('/pieces/red_pawn.svg');
+}
+piece.black.nv-rook {
+  background-image: url('/pieces/red_rook.svg');
+}
+piece.black.nv-knight {
+  background-image: url('/pieces/red_knight.svg');
+}
+piece.black.nv-bishop {
+  background-image: url('/pieces/red_bishop.svg');
+}
+piece.black.nv-queen {
+  background-image: url('/pieces/red_queen.svg');
+}
-- 
2.44.0