Add Forward + Doubleorda variants
[vchess.git] / client / src / variants / Doubleorda.js
diff --git a/client/src/variants/Doubleorda.js b/client/src/variants/Doubleorda.js
new file mode 100644 (file)
index 0000000..290ab23
--- /dev/null
@@ -0,0 +1,148 @@
+import { ChessRules } from "@/base_rules";
+import { OrdaRules } from "@/variants/Orda";
+import { ArrayFun } from "@/utils/array";
+import { randInt } from "@/utils/alea";
+
+export class DoubleordaRules extends OrdaRules {
+  static get PawnSpecs() {
+    return Object.assign(
+      {},
+      ChessRules.PawnSpecs,
+      { promotions: [V.LANCER, V.ARCHER, V.KHESHIG, V.FALCON] }
+    );
+  }
+
+  static get HasFlags() {
+    return false;
+  }
+
+  static get HasEnpassant() {
+    return false;
+  }
+
+  getPpath(b) {
+    return "Orda/" + b;
+  }
+
+  static GenRandInitFen(randomness) {
+    if (randomness == 0)
+      return "lhafkahl/8/pppppppp/8/8/PPPPPPPP/8/LHAFKAHL w 0 ah -";
+
+    let pieces = { w: new Array(8), b: new Array(8) };
+    // Shuffle pieces on first (and last rank if randomness == 2)
+    for (let c of ["w", "b"]) {
+      if (c == 'b' && randomness == 1) {
+        pieces['b'] = pieces['w'];
+        break;
+      }
+
+      let positions = ArrayFun.range(8);
+
+      let randIndex = 2 * randInt(4);
+      const bishop1Pos = positions[randIndex];
+      let randIndex_tmp = 2 * randInt(4) + 1;
+      const bishop2Pos = positions[randIndex_tmp];
+      positions.splice(Math.max(randIndex, randIndex_tmp), 1);
+      positions.splice(Math.min(randIndex, randIndex_tmp), 1);
+
+      randIndex = randInt(6);
+      const knight1Pos = positions[randIndex];
+      positions.splice(randIndex, 1);
+      randIndex = randInt(5);
+      const knight2Pos = positions[randIndex];
+      positions.splice(randIndex, 1);
+
+      randIndex = randInt(4);
+      const queenPos = positions[randIndex];
+      positions.splice(randIndex, 1);
+
+      const rook1Pos = positions[0];
+      const kingPos = positions[1];
+      const rook2Pos = positions[2];
+
+      pieces[c][rook1Pos] = "l";
+      pieces[c][knight1Pos] = "h";
+      pieces[c][bishop1Pos] = "a";
+      pieces[c][queenPos] = "f";
+      pieces[c][kingPos] = "k";
+      pieces[c][bishop2Pos] = "a";
+      pieces[c][knight2Pos] = "h";
+      pieces[c][rook2Pos] = "l";
+    }
+    return (
+      pieces["b"].join("") +
+      "/8/pppppppp/8/8/PPPPPPPP/8/" +
+      pieces["w"].join("").toUpperCase() +
+      " w 0"
+    );
+  }
+
+  static get FALCON() {
+    return 'f';
+  }
+
+  static get PIECES() {
+    return [V.LANCER, V.ARCHER, V.KHESHIG, V.FALCON, V.KING];
+  }
+
+  getPotentialMovesFrom(sq) {
+    switch (this.getPiece(sq[0], sq[1])) {
+      case V.PAWN:
+        return super.getPotentialPawnMoves(sq);
+      case V.LANCER:
+        return super.getPotentialLancerMoves(sq);
+      case V.ARCHER:
+        return super.getPotentialArcherMoves(sq);
+      case V.KHESHIG:
+        return super.getPotentialKheshigMoves(sq);
+      case V.FALCON:
+        return this.getPotentialFalconMoves(sq);
+      case V.KING:
+        return super.getPotentialKingMoves(sq)
+    }
+    return []; //never reached
+  }
+
+  getPotentialFalconMoves(sq) {
+    const onlyMoves = this.getSlideNJumpMoves(
+      sq,
+      V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
+      null,
+      { onlyMove: true }
+    );
+    const onlyTakes = this.getSlideNJumpMoves(
+      sq,
+      V.steps[V.KNIGHT],
+      "oneStep",
+      { onlyTake: true }
+    );
+    return onlyMoves.concat(onlyTakes);
+  }
+
+  isAttacked(sq, color) {
+    return (
+      super.isAttackedByPawn(sq, color) ||
+      super.isAttackedByLancer(sq, color) ||
+      super.isAttackedByKheshig(sq, color) ||
+      super.isAttackedByArcher(sq, color) ||
+      this.isAttackedByFalcon(sq, color) ||
+      super.isAttackedByKing(sq, color)
+    );
+  }
+
+  isAttackedByFalcon(sq, color) {
+    return this.isAttackedBySlideNJump(
+      sq, color, V.FALCON, V.steps[V.KNIGHT], "oneStep");
+  }
+
+  static get VALUES() {
+    return {
+      p: 1,
+      f: 7,
+      a: 4,
+      h: 7,
+      l: 4,
+      k: 1000
+    };
+  }
+};