Several small improvements + integrate options + first working draft of Cwda
[vchess.git] / client / src / variants / Interweave.js
index c776889..3277c74 100644 (file)
@@ -3,17 +3,18 @@ import { ArrayFun } from "@/utils/array";
 import { randInt, shuffle } from "@/utils/alea";
 
 export class InterweaveRules extends ChessRules {
+
   static get HasFlags() {
     return false;
   }
 
-  static GenRandInitFen(randomness) {
-    if (randomness == 0)
+  static GenRandInitFen(options) {
+    if (options.randomness == 0)
       return "rbnkknbr/pppppppp/8/8/8/8/PPPPPPPP/RBNKKNBR w 0 - 000000";
 
     let pieces = { w: new Array(8), b: new Array(8) };
     for (let c of ["w", "b"]) {
-      if (c == 'b' && randomness == 1) {
+      if (c == 'b' && options.randomness == 1) {
         pieces['b'] = pieces['w'];
         break;
       }
@@ -56,7 +57,7 @@ export class InterweaveRules extends ChessRules {
         if (['K','k'].includes(row[i])) kings[row[i]]++;
         if (V.PIECES.includes(row[i].toLowerCase())) sumElts++;
         else {
-          const num = parseInt(row[i]);
+          const num = parseInt(row[i], 10);
           if (isNaN(num)) return false;
           sumElts += num;
         }
@@ -97,18 +98,19 @@ export class InterweaveRules extends ChessRules {
 
   setOtherVariables(fen) {
     super.setOtherVariables(fen);
-    const fenParsed = V.ParseFen(fen);
+    const captured =
+      V.ParseFen(fen).captured.split("").map(x => parseInt(x, 10));
     // Initialize captured pieces' counts from FEN
     this.captured = {
       w: {
-        [V.ROOK]: parseInt(fenParsed.captured[0]),
-        [V.KNIGHT]: parseInt(fenParsed.captured[1]),
-        [V.BISHOP]: parseInt(fenParsed.captured[2]),
+        [V.ROOK]: captured[0],
+        [V.KNIGHT]: captured[1],
+        [V.BISHOP]: captured[2]
       },
       b: {
-        [V.ROOK]: parseInt(fenParsed.captured[3]),
-        [V.KNIGHT]: parseInt(fenParsed.captured[4]),
-        [V.BISHOP]: parseInt(fenParsed.captured[5]),
+        [V.ROOK]: captured[3],
+        [V.KNIGHT]: captured[4],
+        [V.BISHOP]: captured[5]
       }
     };
     // Stack of "last move" only for intermediate captures
@@ -195,56 +197,21 @@ export class InterweaveRules extends ChessRules {
     );
   }
 
-  getPotentialMovesFrom([x, y], noPostprocess) {
-    const L = this.lastMoveEnd.length;
-    if (
-      !!this.lastMoveEnd[L-1] &&
-      (
-        x != this.lastMoveEnd[L-1].x ||
-        y != this.lastMoveEnd[L-1].y
-      )
-    ) {
-      // A capture must continue: wrong square
-      return [];
-    }
-    let moves = [];
+  getPotentialMovesFrom([x, y]) {
     switch (this.getPiece(x, y)) {
       case V.PAWN:
-        moves = this.getPotentialPawnMoves([x, y]);
-        break;
+        return this.getPotentialPawnMoves([x, y]);
       case V.ROOK:
-        moves = this.getPotentialRookMoves([x, y]);
-        break;
+        return this.getPotentialRookMoves([x, y]);
       case V.KNIGHT:
-        moves = this.getPotentialKnightMoves([x, y]);
-        break;
+        return this.getPotentialKnightMoves([x, y]);
       case V.BISHOP:
-        moves = this.getPotentialBishopMoves([x, y]);
-        break;
+        return this.getPotentialBishopMoves([x, y]);
       case V.KING:
-        moves = this.getPotentialKingMoves([x, y]);
-        break;
+        return this.getPotentialKingMoves([x, y]);
       // No queens
     }
-    if (!noPostprocess) {
-      // Post-process: if capture,
-      // can another capture be achieved with the same piece?
-      moves.forEach(m => {
-        if (m.vanish.length >= 2 || m.appear.length == 0) {
-          this.play(m);
-          const moreCaptures = (
-            V.KeepCaptures(
-              this.getPotentialMovesFrom([m.end.x, m.end.y], "noPostprocess")
-            )
-            .length > 0
-          );
-          this.undo(m);
-          if (!moreCaptures) m.last = true;
-        }
-        else m.last = true;
-      });
-    }
-    return moves;
+    return [];
   }
 
   // Special pawns movements
@@ -590,11 +557,23 @@ export class InterweaveRules extends ChessRules {
       for (let i=1; i<move.vanish.length; i++)
         this.captured[move.vanish[i].c][move.vanish[i].p]++;
     }
+    // Check if the move is the last of the turn
+    if (move.vanish.length >= 2 || move.appear.length == 0) {
+      const moreCaptures = (
+        V.KeepCaptures(
+          this.getPotentialMovesFrom([move.end.x, move.end.y])
+        )
+        .length > 0
+      );
+      move.last = !moreCaptures;
+    }
+    else move.last = true;
     if (!!move.last) {
       // No capture, or no more capture available
       this.turn = V.GetOppCol(this.turn);
       this.movesCount++;
       this.lastMoveEnd.push(null);
+      move.last = true; //will be used in undo and computer play
     }
     else this.lastMoveEnd.push(move.end);
   }
@@ -639,14 +618,14 @@ export class InterweaveRules extends ChessRules {
     while (moves.length > 0) {
       const mv = moves[randInt(moves.length)];
       mvArray.push(mv);
+      this.play(mv);
       if (!mv.last) {
-        this.play(mv);
         moves = V.KeepCaptures(
           this.getPotentialMovesFrom([mv.end.x, mv.end.y]));
       }
       else break;
     }
-    for (let i = mvArray.length - 2; i >= 0; i--) this.undo(mvArray[i]);
+    for (let i = mvArray.length - 1; i >= 0; i--) this.undo(mvArray[i]);
     return (mvArray.length > 1 ? mvArray : mvArray[0]);
   }
 
@@ -661,4 +640,5 @@ export class InterweaveRules extends ChessRules {
     if (move.vanish.length >= 2) notation += "X";
     return notation;
   }
+
 };