From 296f846a620c361b3fe4e61f6bb369adc361d312 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Wed, 26 Jul 2023 12:23:13 +0200
Subject: [PATCH] Copycat almost ok - some checks undetected

---
 base_rules.js               |  2 ++
 variants.js                 |  2 +-
 variants/Copycat/class.js   | 63 +++++++++++++++++++++++++++++++++++++
 variants/Copycat/rules.html |  8 +++++
 variants/Copycat/style.css  |  1 +
 5 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 variants/Copycat/class.js
 create mode 100644 variants/Copycat/rules.html
 create mode 100644 variants/Copycat/style.css

diff --git a/base_rules.js b/base_rules.js
index c0d9b60..9cedfd0 100644
--- a/base_rules.js
+++ b/base_rules.js
@@ -1838,6 +1838,8 @@ export default class ChessRules {
     }
   }
 
+  // TODO here: should/could use getPotentialMovesFrom ?! (not sure)
+  // --> would be useful for variants like Copycat.
   // Search for enemy (or not) pieces attacking [x, y]
   findCapturesOn([x, y], o, allowed) {
     if (!o.byCol)
diff --git a/variants.js b/variants.js
index 182fb8f..dad687f 100644
--- a/variants.js
+++ b/variants.js
@@ -33,7 +33,7 @@ const variants = [
   {name: 'Circular', desc: 'Run forward'},
   {name: 'Clorange', desc: 'A Clockwork Orange', disp: 'Clockwork Orange'},
   {name: 'Convert', desc: 'Convert enemy pieces'},
-//  {name: 'Copycat', desc: 'Borrow powers'},
+  {name: 'Copycat', desc: 'Borrow powers'},
 //  {name: 'Coregal', desc: 'Two royal pieces'},
 //  {name: 'Coronation', desc: 'Long live the Queen'},
   {name: 'Crazyhouse', desc: 'Captures reborn'},
diff --git a/variants/Copycat/class.js b/variants/Copycat/class.js
new file mode 100644
index 0000000..2c417c5
--- /dev/null
+++ b/variants/Copycat/class.js
@@ -0,0 +1,63 @@
+import ChessRules from "/base_rules.js";
+
+export default class CopycatRules extends ChessRules {
+
+  static get Options() {
+    return {
+      select: C.Options.select,
+      input: C.Options.input,
+      styles: ["atomic", "capture", "crazyhouse", "cylinder", "dark", "zen"]
+    };
+  }
+
+  getPotentialMovesFrom([x, y], color) {
+    let moves = super.getPotentialMovesFrom([x, y], color);
+    // Expand potential moves if attacking friendly pieces.
+    const piece = this.getPiece(x,y);
+    if (['p', 'k'].includes(piece))
+      return moves;
+    let movements = {};
+    const steps = this.pieces()[piece].both[0].steps;
+    steps.forEach(s => {
+      let [i, j] = [x + s[0], y + s[1]];
+      while (
+        this.onBoard(i, j) &&
+        this.board[i][j] == "" &&
+        piece != 'n'
+      ) {
+        i += s[0];
+        j += s[1];
+      }
+      if (this.onBoard(i, j) && this.getColor(i, j) == this.turn) {
+        const attacked = this.getPiece(i, j);
+        if (['r', 'b', 'n'].includes(attacked)) {
+          if (!movements[attacked])
+            movements[attacked] = true;
+        }
+        else if (attacked == 'q') {
+          if (!movements['r'])
+            movements['r'] = true;
+          if (!movements['b'])
+            movements['b'] = true;
+        }
+      }
+    });
+    Object.keys(movements).forEach(type => {
+      if (
+        (piece != 'q' && type != piece) ||
+        (piece == 'q' && type == 'n')
+      ) {
+        Array.prototype.push.apply(moves,
+          super.getPotentialMovesOf(type, [x, y]));
+      }
+    });
+    return moves;
+  }
+
+  underAttack([x, y], oppCols) {
+    if (super.underAttack([x, y], oppCols)
+      return true;
+    //TODO
+  }
+
+};
diff --git a/variants/Copycat/rules.html b/variants/Copycat/rules.html
new file mode 100644
index 0000000..43d1f25
--- /dev/null
+++ b/variants/Copycat/rules.html
@@ -0,0 +1,8 @@
+<p>
+  If a piece (rook, knight, bishop or queen) attacks another friendly one,
+  it borrows powers from it and can move (and capture) like it.
+</p>
+
+<p class="author">Students from the <a href="https://www.facebook.com/groups/ucfchessclub/">UCF Chess Club</a> (2020).</p>
+
+<p>See also their <a href="https://discord.gg/tv9hVkQKa9">Discord server</a> :-)</p>
diff --git a/variants/Copycat/style.css b/variants/Copycat/style.css
new file mode 100644
index 0000000..a3550bc
--- /dev/null
+++ b/variants/Copycat/style.css
@@ -0,0 +1 @@
+@import url("/base_pieces.css");
-- 
2.44.0