Experimental change: options replacing randomness (more general)
[vchess.git] / client / src / variants / Allmate2.js
diff --git a/client/src/variants/Allmate2.js b/client/src/variants/Allmate2.js
deleted file mode 100644 (file)
index f4abbe3..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-import { ChessRules, PiPo, Move } from "@/base_rules";
-
-export class Allmate2Rules extends ChessRules {
-
-  static get HasEnpassant() {
-    return false;
-  }
-
-  getCheckSquares() {
-    // No notion of check
-    return [];
-  }
-
-  static GenRandInitFen(randomness) {
-    return ChessRules.GenRandInitFen(randomness).slice(0, -2);
-  }
-
-  getPotentialMovesFrom([x, y]) {
-    let moves = super.getPotentialMovesFrom([x, y]);
-    // Remove standard captures (without removing castling):
-    moves = moves.filter(m => {
-      return m.vanish.length == 1 || m.appear.length == 2;
-    });
-
-    // Augment moves with "mate-captures":
-    // TODO: this is coded in a highly inefficient way...
-    const color = this.turn;
-    const oppCol = V.GetOppCol(this.turn);
-    moves.forEach(m => {
-      this.play(m);
-
-      // 1) What is attacked?
-      let attacked = {};
-      for (let i=0; i<V.size.x; i++) {
-        for (let j=0; j<V.size.y; j++) {
-          if (this.getColor(i,j) == oppCol && this.isAttacked([i,j], color))
-            attacked[i+"_"+j] = [i,j];
-        }
-      }
-
-      // 2) Among attacked pieces, which cannot escape capture?
-      // --> without (normal-)capturing: difference with Allmate1 variant
-      // Avoid "oppMoves = this.getAllValidMoves();" => infinite recursion
-      outerLoop: for (let i=0; i<V.size.x; i++) {
-        for (let j=0; j<V.size.y; j++) {
-          if (this.getColor(i,j) == oppCol) {
-            let oppMoves = [];
-            switch (this.getPiece(i, j)) {
-              case V.PAWN:
-                oppMoves = this.getPotentialPawnMoves([i, j]);
-                break;
-              case V.ROOK:
-                oppMoves = this.getPotentialRookMoves([i, j]);
-                break;
-              case V.KNIGHT:
-                oppMoves = this.getPotentialKnightMoves([i, j]);
-                break;
-              case V.BISHOP:
-                oppMoves = this.getPotentialBishopMoves([i, j]);
-                break;
-              case V.QUEEN:
-                oppMoves = this.getPotentialQueenMoves([i, j]);
-                break;
-              case V.KING:
-                // Do not allow castling to escape from check
-                oppMoves = super.getSlideNJumpMoves(
-                  [i, j],
-                  V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
-                  "oneStep"
-                );
-                break;
-            }
-            for (let om of oppMoves) {
-              if (om.vanish.length == 2)
-                // Skip captures: forbidden in this mode
-                continue;
-              V.PlayOnBoard(this.board, om);
-              Object.values(attacked).forEach(sq => {
-                const origSq = [sq[0], sq[1]];
-                if (om.start.x == sq[0] && om.start.y == sq[1])
-                  // Piece moved:
-                  sq = [om.appear[0].x, om.appear[0].y];
-                if (!this.isAttacked(sq, color))
-                  delete attacked[origSq[0]+"_"+origSq[1]];
-              });
-              V.UndoOnBoard(this.board, om);
-              if (Object.keys(attacked).length == 0)
-                // No need to explore more moves
-                break outerLoop;
-            }
-          }
-        }
-      }
-      this.undo(m);
-
-      // 3) Add mate-captures:
-      Object.values(attacked).forEach(sq => {
-        m.vanish.push(new PiPo({
-          x: sq[0],
-          y: sq[1],
-          c: oppCol,
-          p: this.getPiece(sq[0], sq[1])
-        }));
-      });
-    });
-
-    return moves;
-  }
-
-  // No "under check" conditions in castling
-  getCastleMoves(sq) {
-    return super.getCastleMoves(sq, null, "castleInCheck");
-  }
-
-  // TODO: allow pieces to "commit suicide"? (Currently yes except king)
-  filterValid(moves) {
-    // Remove moves which let the king mate-captured:
-    if (moves.length == 0) return [];
-    const color = this.turn;
-    const oppCol = V.GetOppCol(color);
-    return moves.filter(m => {
-      let res = true;
-      this.play(m);
-      if (this.underCheck(color)) {
-        res = false;
-        const attacked = this.kingPos[color];
-        // Try to find a move to escape check
-        // TODO: very inefficient method.
-        outerLoop: for (let i=0; i<V.size.x; i++) {
-          for (let j=0; j<V.size.y; j++) {
-            if (this.getColor(i,j) == color) {
-              let emoves = [];
-              // Artficial turn change to "play twice":
-              this.turn = color;
-              switch (this.getPiece(i, j)) {
-                case V.PAWN:
-                  emoves = this.getPotentialPawnMoves([i, j]);
-                  break;
-                case V.ROOK:
-                  emoves = this.getPotentialRookMoves([i, j]);
-                  break;
-                case V.KNIGHT:
-                  emoves = this.getPotentialKnightMoves([i, j]);
-                  break;
-                case V.BISHOP:
-                  emoves = this.getPotentialBishopMoves([i, j]);
-                  break;
-                case V.QUEEN:
-                  emoves = this.getPotentialQueenMoves([i, j]);
-                  break;
-                case V.KING:
-                  emoves = this.getPotentialKingMoves([i, j]);
-                  break;
-              }
-              this.turn = oppCol;
-              for (let em of emoves) {
-                V.PlayOnBoard(this.board, em);
-                let sq = attacked;
-                if (em.start.x == attacked[0] && em.start.y == attacked[1])
-                  // King moved:
-                  sq = [em.appear[0].x, em.appear[0].y];
-                if (!this.isAttacked(sq, oppCol))
-                  res = true;
-                V.UndoOnBoard(this.board, em);
-                if (res)
-                  // No need to explore more moves
-                  break outerLoop;
-              }
-            }
-          }
-        }
-      }
-      this.undo(m);
-      return res;
-    });
-  }
-
-  postPlay(move) {
-    super.postPlay(move);
-    if (move.vanish.length >= 2 && move.appear.length == 1) {
-      for (let i = 1; i<move.vanish.length; i++) {
-        const v = move.vanish[i];
-        // Did opponent king disappeared?
-        if (v.p == V.KING)
-          this.kingPos[this.turn] = [-1, -1];
-        // Or maybe a rook?
-        else if (v.p == V.ROOK) {
-          if (v.y < this.kingPos[v.c][1])
-            this.castleFlags[v.c][0] = 8;
-          else
-            // v.y > this.kingPos[v.c][1]
-            this.castleFlags[v.c][1] = 8;
-        }
-      }
-    }
-  }
-
-  preUndo(move) {
-    super.preUndo(move);
-    const oppCol = this.turn;
-    if (move.vanish.length >= 2 && move.appear.length == 1) {
-      // Did opponent king disappeared?
-      const psq = move.vanish.find(v => v.p == V.KING && v.c == oppCol)
-      if (psq)
-        this.kingPos[psq.c] = [psq.x, psq.y];
-    }
-  }
-
-  getCurrentScore() {
-    const color = this.turn;
-    const kp = this.kingPos[color];
-    if (kp[0] < 0)
-      // King disappeared
-      return color == "w" ? "0-1" : "1-0";
-    if (this.atLeastOneMove()) return "*";
-    // Kings still there, no moves:
-    return "1/2";
-  }
-
-  static get SEARCH_DEPTH() {
-    return 1;
-  }
-
-  getNotation(move) {
-    let notation = super.getNotation(move);
-    // Add a capture mark (not describing what is captured...):
-    if (move.vanish.length > 1 && move.appear.length == 1) {
-      if (!!(notation.match(/^[a-h]x/)))
-        // Pawn capture: remove initial "b" in bxc4 for example
-        notation = notation.substr(1);
-      notation = notation.replace("x","") + "X";
-    }
-    return notation;
-  }
-
-};