Draft Hiddenqueen, Grasshopper and Knightmate chess (rules unwritten)
[vchess.git] / client / src / variants / Enpassant.js
index 374a620..3f8f3b2 100644 (file)
@@ -67,6 +67,52 @@ export const VariantRules = class EnpassantRules extends ChessRules {
     return res.slice(0, -1); //remove last comma
   }
 
+  getPotentialMovesFrom([x, y]) {
+    let moves = super.getPotentialMovesFrom([x,y]);
+    // Add en-passant captures from this square:
+    const L = this.epSquares.length;
+    if (!this.epSquares[L - 1]) return moves;
+    const squares = this.epSquares[L - 1];
+    const S = squares.length;
+    // Object describing the removed opponent's piece:
+    const pipoV = new PiPo({
+      x: squares[S-1].x,
+      y: squares[S-1].y,
+      c: V.GetOppCol(this.turn),
+      p: this.getPiece(squares[S-1].x, squares[S-1].y)
+    });
+    // Check if existing non-capturing moves could also capture en passant
+    moves.forEach(m => {
+      if (
+        m.appear[0].p != V.PAWN && //special pawn case is handled elsewhere
+        m.vanish.length <= 1 &&
+        [...Array(S-1).keys()].some(i => {
+          return m.end.x == squares[i].x && m.end.y == squares[i].y;
+        })
+      ) {
+        m.vanish.push(pipoV);
+      }
+    });
+    // Special case of the king knight's movement:
+    if (this.getPiece(x, y) == V.KING) {
+      V.steps[V.KNIGHT].forEach(step => {
+        const endX = x + step[0];
+        const endY = y + step[1];
+        if (
+          V.OnBoard(endX, endY) &&
+          [...Array(S-1).keys()].some(i => {
+            return endX == squares[i].x && endY == squares[i].y;
+          })
+        ) {
+          let enpassantMove = this.getBasicMove([x, y], [endX, endY]);
+          enpassantMove.vanish.push(pipoV);
+          moves.push(enpassantMove);
+        }
+      });
+    }
+    return moves;
+  }
+
   // TODO: this getPotentialPawnMovesFrom() is mostly duplicated:
   // it could be split in "capture", "promotion", "enpassant"...
   getPotentialPawnMoves([x, y]) {
@@ -144,11 +190,19 @@ export const VariantRules = class EnpassantRules extends ChessRules {
   }
 
   // Remove the "onestep" condition: knight promote to knightrider:
-
   getPotentialKnightMoves(sq) {
     return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT]);
   }
 
+  filterValid(moves) {
+    const filteredMoves = super.filterValid(moves);
+    // If at least one full move made, everything is allowed:
+    if (this.movesCount >= 2)
+      return filteredMoves;
+    // Else, forbid captures:
+    return filteredMoves.filter(m => m.vanish.length == 1);
+  }
+
   isAttackedByKnight(sq, colors) {
     return this.isAttackedBySlideNJump(
       sq,
@@ -158,52 +212,6 @@ export const VariantRules = class EnpassantRules extends ChessRules {
     );
   }
 
-  getPotentialMovesFrom([x, y]) {
-    let moves = super.getPotentialMovesFrom([x,y]);
-    // Add en-passant captures from this square:
-    const L = this.epSquares.length;
-    if (!this.epSquares[L - 1]) return moves;
-    const squares = this.epSquares[L - 1];
-    const S = squares.length;
-    // Object describing the removed opponent's piece:
-    const pipoV = new PiPo({
-      x: squares[S-1].x,
-      y: squares[S-1].y,
-      c: V.GetOppCol(this.turn),
-      p: this.getPiece(squares[S-1].x, squares[S-1].y)
-    });
-    // Check if existing non-capturing moves could also capture en passant
-    moves.forEach(m => {
-      if (
-        m.appear[0].p != V.PAWN && //special pawn case is handled elsewhere
-        m.vanish.length <= 1 &&
-        [...Array(S-1).keys()].some(i => {
-          return m.end.x == squares[i].x && m.end.y == squares[i].y;
-        })
-      ) {
-        m.vanish.push(pipoV);
-      }
-    });
-    // Special case of the king knight's movement:
-    if (this.getPiece(x, y) == V.KING) {
-      V.steps[V.KNIGHT].forEach(step => {
-        const endX = x + step[0];
-        const endY = y + step[1];
-        if (
-          V.OnBoard(endX, endY) &&
-          [...Array(S-1).keys()].some(i => {
-            return endX == squares[i].x && endY == squares[i].y;
-          })
-        ) {
-          let enpassantMove = this.getBasicMove([x, y], [endX, endY]);
-          enpassantMove.vanish.push(pipoV);
-          moves.push(enpassantMove);
-        }
-      });
-    }
-    return moves;
-  }
-
   static get VALUES() {
     return {
       p: 1,