From 9a7a1ccca45d083f50d92bc15cd389c14149b50a Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Mon, 28 Dec 2020 14:38:05 +0100
Subject: [PATCH] Fix Atomic2, Hamilton (hover, click) + Knightrelay1 (king not
 relayed)

---
 client/src/components/Board.vue     | 68 ++++++++++++++---------------
 client/src/variants/Atomic2.js      |  6 +++
 client/src/variants/Knightrelay1.js |  7 ++-
 client/src/variants/Teleport.js     |  5 +++
 4 files changed, 50 insertions(+), 36 deletions(-)

diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue
index 313564d2..1d650ac0 100644
--- a/client/src/components/Board.vue
+++ b/client/src/components/Board.vue
@@ -648,45 +648,45 @@ export default {
             document.getElementById("boardContainer").getBoundingClientRect();
           // NOTE: classList[0] is enough: 'piece' is the first assigned class
           const withPiece = (e.target.classList[0] == "piece");
-          // Emit the click event which could be used by some variants
-          this.$emit(
-            "click-square",
-            getSquareFromId(withPiece ? e.target.parentNode.id : e.target.id)
-          );
-          // Start square must contain a piece.
-          if (!withPiece) return;
-          let parent = e.target.parentNode; //surrounding square
           // Show possible moves if current player allowed to play
-          const startSquare = getSquareFromId(parent.id);
+          const startSquare =
+            getSquareFromId(withPiece ? e.target.parentNode.id : e.target.id);
           this.possibleMoves = [];
           const color = this.analyze ? this.vr.turn : this.userColor;
-          if (this.vr.canIplay(color, startSquare))
-            this.possibleMoves = this.vr.getPossibleMovesFrom(startSquare);
-          else return;
-          // For potential drag'n drop, remember start coordinates
-          // (to center the piece on mouse cursor)
-          const rect = parent.getBoundingClientRect();
-          this.start = {
-            x: rect.x + rect.width / 2,
-            y: rect.y + rect.width / 2,
-            id: parent.id
-          };
-          // Add the moving piece to the board, just after current image
-          this.selectedPiece = e.target.cloneNode();
-          Object.assign(
-            this.selectedPiece.style,
-            {
-              position: "absolute",
-              top: 0,
-              display: "inline-block",
-              zIndex: 3000
+          if (this.vr.canIplay(color, startSquare)) {
+            // Emit the click event which could be used by some variants
+            const targetId =
+              (withPiece ? e.target.parentNode.id : e.target.id);
+            this.$emit("click-square", getSquareFromId(targetId));
+            if (withPiece) {
+              this.possibleMoves = this.vr.getPossibleMovesFrom(startSquare);
+              // For potential drag'n drop, remember start coordinates
+              // (to center the piece on mouse cursor)
+              let parent = e.target.parentNode; //surrounding square
+              const rect = parent.getBoundingClientRect();
+              this.start = {
+                x: rect.x + rect.width / 2,
+                y: rect.y + rect.width / 2,
+                id: parent.id
+              };
+              // Add the moving piece to the board, just after current image
+              this.selectedPiece = e.target.cloneNode();
+              Object.assign(
+                this.selectedPiece.style,
+                {
+                  position: "absolute",
+                  top: 0,
+                  display: "inline-block",
+                  zIndex: 3000
+                }
+              );
+              parent.insertBefore(this.selectedPiece, e.target.nextSibling);
             }
-          );
-          parent.insertBefore(this.selectedPiece, e.target.nextSibling);
-        } else {
-          this.processMoveAttempt(e);
+          }
         }
-      } else if (e.which == 3) {
+        else this.processMoveAttempt(e);
+      }
+      else if (e.which == 3) {
         // Mouse right button
         this.containerPos =
           document.getElementById("gamePosition").getBoundingClientRect();
diff --git a/client/src/variants/Atomic2.js b/client/src/variants/Atomic2.js
index 9ea22961..f97be01c 100644
--- a/client/src/variants/Atomic2.js
+++ b/client/src/variants/Atomic2.js
@@ -27,6 +27,12 @@ export class Atomic2Rules extends Atomic1Rules {
     return this.movesCount == 0 && [1, 6].includes(x);
   }
 
+  canIplay(side, [x, y]) {
+    if (this.movesCount == 0)
+      return (this.turn == side && this.getPiece(x, y) == V.PAWN);
+    return super.canIplay(side, [x, y]);
+  }
+
   doClick(square) {
     if (this.movesCount >= 1) return null;
     const [x, y] = [square[0], square[1]];
diff --git a/client/src/variants/Knightrelay1.js b/client/src/variants/Knightrelay1.js
index aba95290..0afa9aa2 100644
--- a/client/src/variants/Knightrelay1.js
+++ b/client/src/variants/Knightrelay1.js
@@ -73,7 +73,7 @@ export class Knightrelay1Rules extends ChessRules {
 
     // Check if a (non-knight) piece at knight distance
     // is guarded by a knight (and thus attacking)
-    // --> Except for pawns targetting last rank.
+    // --> Except for kings, and pawns targetting last rank.
     const x = sq[0],
           y = sq[1];
     // Last rank for me, that is to say oppCol of color:
@@ -84,7 +84,10 @@ export class Knightrelay1Rules extends ChessRules {
         this.getColor(x+step[0],y+step[1]) == color
       ) {
         const piece = this.getPiece(x+step[0],y+step[1]);
-        if (piece != V.KNIGHT && (piece != V.PAWN || x != lastRank)) {
+        if (
+          ![V.KNIGHT, V.KING].includes(piece) &&
+          (piece != V.PAWN || x != lastRank)
+        ) {
           for (const step2 of V.steps[V.KNIGHT]) {
             const xx = x+step[0]+step2[0],
                   yy = y+step[1]+step2[1];
diff --git a/client/src/variants/Teleport.js b/client/src/variants/Teleport.js
index 52c7fd6e..82528c18 100644
--- a/client/src/variants/Teleport.js
+++ b/client/src/variants/Teleport.js
@@ -19,6 +19,11 @@ export class TeleportRules extends ChessRules {
     return this.subTurn == 1;
   }
 
+  canIplay(side, [x, y]) {
+    if (this.subTurn == 2) return (this.board[x][y] == V.EMPTY);
+    return super.canIplay(side, [x, y]);
+  }
+
   getPPpath(m) {
     if (
       m.vanish.length == 2 &&
-- 
2.44.0