Fix games download/upload + Dynamo variant
[vchess.git] / client / src / variants / Dynamo.js
index 9c0d080..5955f64 100644 (file)
@@ -158,7 +158,6 @@ export class DynamoRules extends ChessRules {
   }
 
   // There was something on x2,y2, maybe our color, pushed/pulled.
-  // Also, the pushed/pulled piece must exit the board.
   isAprioriValidExit([x1, y1], [x2, y2], color2) {
     const color1 = this.getColor(x1, y1);
     const pawnShift = (color1 == 'w' ? -1 : 1);
@@ -208,11 +207,28 @@ export class DynamoRules extends ChessRules {
     return false;
   }
 
+  isAprioriValidVertical([x1, y1], x2) {
+    const piece = this.getPiece(x1, y1);
+    const deltaX = Math.abs(x1 - x2);
+    const startRank = (this.getColor(x1, y1) == 'w' ? 6 : 1);
+    return (
+      [V.QUEEN, V.ROOK].includes(piece) ||
+      (
+        [V.KING, V.PAWN].includes(piece) &&
+        (
+          deltaX == 1 ||
+          (deltaX == 2 && piece == V.PAWN && x1 == startRank)
+        )
+      )
+    );
+  }
+
   // NOTE: for pushes, play the pushed piece first.
   //       for pulls: play the piece doing the action first
   // NOTE: to push a piece out of the board, make it slide until its king
   getPotentialMovesFrom([x, y]) {
     const color = this.turn;
+    const sqCol = this.getColor(x, y);
     if (this.subTurn == 1) {
       const getMoveHash = (m) => {
         return V.CoordsToSquare(m.start) + V.CoordsToSquare(m.end);
@@ -226,7 +242,7 @@ export class DynamoRules extends ChessRules {
       };
       // Free to play any move (if piece of my color):
       let moves =
-        this.getColor(x, y) == color
+        sqCol == color
           ? super.getPotentialMovesFrom([x, y])
           : [];
       // There may be several suicide moves: keep only one
@@ -276,13 +292,12 @@ export class DynamoRules extends ChessRules {
                 deltaX <= 2 &&
                 deltaY <= 1
               ) {
-                const pColor = this.getColor(x, y);
-                if (pColor == color && deltaY == 0) {
+                if (sqCol == color && deltaY == 0) {
                   // Pushed forward
                   const maxSteps = (i == pawnStartRank && deltaX == 1 ? 2 : 1);
                   addMoves(step, maxSteps);
                 }
-                else if (pColor != color && deltaY == 1 && deltaX == 1)
+                else if (sqCol != color && deltaY == 1 && deltaX == 1)
                   // Pushed diagonally
                   addMoves(step, 1);
               }
@@ -311,13 +326,19 @@ export class DynamoRules extends ChessRules {
     // naturally limited in those cases.
     const L = this.firstMove.length;
     const fm = this.firstMove[L-1];
-    if (fm.appear.length == 2 && fm.vanish.length == 2)
-      // Castle: no real move playable then.
+    if (
+      (fm.appear.length == 2 && fm.vanish.length == 2) ||
+      (fm.vanish[0].c == sqCol && sqCol != color)
+    ) {
+      // Castle or again opponent color: no move playable then.
       return [];
+    }
     if (fm.appear.length == 0) {
       // Piece at subTurn 1 just exited the board.
       // Can I be a piece which caused the exit?
       if (
+        // Only "turn" color can do actions
+        sqCol == color &&
         this.isAprioriValidExit(
           [x, y],
           [fm.start.x, fm.start.y],
@@ -327,7 +348,9 @@ export class DynamoRules extends ChessRules {
         // Seems so:
         const dir = this.getNormalizedDirection(
           [fm.start.x - x, fm.start.y - y]);
-        return this.getMovesInDirection([x, y], dir);
+        const nbSteps =
+          ([V.PAWN,V.KING,V.KNIGHT].includes(this.getPiece(x, y)) ? 1 : null);
+        return this.getMovesInDirection([x, y], dir, nbSteps);
       }
     }
     else {
@@ -337,6 +360,15 @@ export class DynamoRules extends ChessRules {
         [fm.start.x - x, fm.start.y - y]);
       // Normalized directions should match
       if (dir[0] == dirM[0] && dir[1] == dirM[1]) {
+        // If first move is a pawn move, only a queen, rook, or maybe king or
+        // pawn can follow (need vertical movement option).
+        if (
+          fm.vanish[0].p == V.PAWN &&
+          fm.vanish[0].c == color &&
+          !this.isAprioriValidVertical([x, y], fm.start.x)
+        ) {
+          return [];
+        }
         // And nothing should stand between [x, y] and the square fm.start
         let [i, j] = [x + dir[0], y + dir[1]];
         while (
@@ -355,6 +387,8 @@ export class DynamoRules extends ChessRules {
 
   getSlideNJumpMoves([x, y], steps, oneStep) {
     let moves = [];
+    const c = this.getColor(x, y);
+    const piece = this.getPiece(x, y);
     outerLoop: for (let step of steps) {
       let i = x + step[0];
       let j = y + step[1];
@@ -370,9 +404,7 @@ export class DynamoRules extends ChessRules {
       }
       else {
         // Add potential board exit (suicide), except for the king
-        const piece = this.getPiece(x, y);
         if (piece != V.KING) {
-          const c = this.getColor(x, y);
           moves.push({
             start: { x: x, y: y},
             end: { x: this.kingPos[c][0], y: this.kingPos[c][1] },