Some fixes, draw lines on board, add 7 variants
[vchess.git] / client / src / variants / Ball.js
index 734a921..ceddb61 100644 (file)
@@ -3,6 +3,21 @@ import { ArrayFun } from "@/utils/array";
 import { shuffle } from "@/utils/alea";
 
 export class BallRules extends ChessRules {
+  static get Lines() {
+    return [
+      // White goal:
+      [[0, 3], [0, 6]],
+      [[0, 6], [1, 6]],
+      [[1, 6], [1, 3]],
+      [[1, 3], [0, 3]],
+      // Black goal:
+      [[9, 3], [9, 6]],
+      [[9, 6], [8, 6]],
+      [[8, 6], [8, 3]],
+      [[8, 3], [9, 3]]
+    ];
+  }
+
   static get PawnSpecs() {
     return Object.assign(
       {},
@@ -112,14 +127,21 @@ export class BallRules extends ChessRules {
   }
 
   canTake([x1, y1], [x2, y2]) {
-    // Capture enemy or pass ball to friendly pieces
+    if (this.getColor(x1, y1) !== this.getColor(x2, y2)) {
+      // The piece holding the ball cannot capture:
+      return (
+        !(Object.keys(V.HAS_BALL_DECODE)
+          .includes(this.board[x1][y1].charAt(1)))
+      );
+    }
+    // Pass: possible only if one of the friendly pieces has the ball
     return (
-      this.getColor(x1, y1) !== this.getColor(x2, y2) ||
-      Object.keys(V.HAS_BALL_DECODE).includes(this.board[x1][y1].charAt(1))
+      Object.keys(V.HAS_BALL_DECODE).includes(this.board[x1][y1].charAt(1)) ||
+      Object.keys(V.HAS_BALL_DECODE).includes(this.board[x2][y2].charAt(1))
     );
   }
 
-  getCheckSquares(color) {
+  getCheckSquares() {
     return [];
   }
 
@@ -238,15 +260,29 @@ export class BallRules extends ChessRules {
       );
     }
 
-    // Post-processing: maybe the ball was taken, or a piece + ball
+    // Post-processing: maybe the ball was taken, or a piece + ball,
+    // or maybe a pass (ball <--> piece)
     if (mv.vanish.length == 2) {
       if (
         // Take the ball?
         mv.vanish[1].c == 'a' ||
-        // Capture a ball-holding piece?
+        // Capture a ball-holding piece? If friendly one, then adjust
         Object.keys(V.HAS_BALL_DECODE).includes(mv.vanish[1].p)
       ) {
         mv.appear[0].p = V.HAS_BALL_CODE[mv.appear[0].p];
+        if (mv.vanish[1].c == mv.vanish[0].c) {
+          // "Capturing" self => pass
+          mv.appear[0].x = mv.start.x;
+          mv.appear[0].y = mv.start.y;
+          mv.appear.push(
+            new PiPo({
+              x: mv.end.x,
+              y: mv.end.y,
+              p: V.HAS_BALL_DECODE[mv.vanish[1].p],
+              c: mv.vanish[0].c
+            })
+          );
+        }
       } else if (mv.vanish[1].c == mv.vanish[0].c) {
         // Pass the ball: the passing unit does not disappear
         mv.appear.push(JSON.parse(JSON.stringify(mv.vanish[0])));
@@ -268,7 +304,7 @@ export class BallRules extends ChessRules {
     return super.getPotentialMovesFrom([x, y]);
   }
 
-  // "Sliders": at most 2 steps
+  // "Sliders": at most 3 steps
   getSlideNJumpMoves([x, y], steps, oneStep) {
     let moves = [];
     outerLoop: for (let step of steps) {
@@ -277,7 +313,7 @@ export class BallRules extends ChessRules {
       let stepCount = 1;
       while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
         moves.push(this.getBasicMove([x, y], [i, j]));
-        if (oneStep || stepCount == 2) continue outerLoop;
+        if (oneStep || stepCount == 3) continue outerLoop;
         i += step[0];
         j += step[1];
         stepCount++;