Fix Shogi.js
[vchess.git] / client / src / variants / Shogi.js
index e8b1791..5f85e75 100644 (file)
@@ -16,10 +16,19 @@ export class ShogiRules extends ChessRules {
     return true;
   }
 
+  get showFirstTurn() {
+    return true;
+  }
+
   static get Notoodark() {
     return true;
   }
 
+  loseOnRepetition() {
+    // If current side is under check: lost
+    return this.underCheck(this.turn);
+  }
+
   static IsGoodFen(fen) {
     if (!ChessRules.IsGoodFen(fen)) return false;
     const fenParsed = V.ParseFen(fen);
@@ -104,8 +113,8 @@ export class ShogiRules extends ChessRules {
     );
   }
 
-  static GenRandInitFen(randomness) {
-    if (randomness == 0) {
+  static GenRandInitFen(options) {
+    if (options.randomness == 0) {
       return (
         "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL " +
         "w 0 00000000000000"
@@ -116,7 +125,7 @@ export class ShogiRules extends ChessRules {
     let pieces1 = { w: new Array(4), b: new Array(4) };
     let positions2 = { w: new Array(2), b: new Array(2) };
     for (let c of ["w", "b"]) {
-      if (c == 'b' && randomness == 1) {
+      if (c == 'b' && options.randomness == 1) {
         pieces1['b'] = JSON.parse(JSON.stringify(pieces1['w'])).reverse();
         positions2['b'] =
           JSON.parse(JSON.stringify(positions2['w'])).reverse()
@@ -278,7 +287,9 @@ export class ShogiRules extends ChessRules {
           if (p == V.PAWN) {
             // Do not drop on checkmate:
             this.play(mv);
-            const res = (this.underCheck(oppCol) && !this.atLeastOneMove());
+            const res = (
+              this.underCheck(oppCol) && !this.atLeastOneMove("noReserve")
+            );
             this.undo(mv);
             if (res) continue;
           }
@@ -308,7 +319,7 @@ export class ShogiRules extends ChessRules {
       case V.LANCE:
         return this.getPotentialLanceMoves([x, y]);
       case V.KING:
-        return this.getPotentialKingMoves([x, y]);
+        return super.getPotentialKingMoves([x, y]);
       case V.P_ROOK:
         return this.getPotentialDragonMoves([x, y]);
       case V.P_BISHOP:
@@ -415,7 +426,7 @@ export class ShogiRules extends ChessRules {
     const forward = (this.turn == 'w' ? -1 : 1);
     return this.getSlideNJumpMoves(
       sq,
-      [[forward, 0]],
+      [ [forward, 0] ],
       {
         promote: V.P_LANCE,
         force: true
@@ -447,14 +458,6 @@ export class ShogiRules extends ChessRules {
     );
   }
 
-  getPotentialKingMoves(sq) {
-    return this.getSlideNJumpMoves(
-      sq,
-      V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
-      { oneStep: true }
-    );
-  }
-
   isAttacked(sq, color) {
     return (
       this.isAttackedByPawn(sq, color) ||
@@ -487,37 +490,21 @@ export class ShogiRules extends ChessRules {
     return false;
   }
 
-  isAttackedBySilver([x, y], color) {
+  isAttackedBySilver(sq, color) {
     const shift = (color == 'w' ? 1 : -1);
-    for (let step of V.steps[V.BISHOP].concat([[shift, 0]])) {
-      const [i, j] = [x + step[0], y + step[1]];
-      if (
-        V.OnBoard(i, j) &&
-        this.board[i][j] != V.EMPTY &&
-        this.getColor(i, j) == color &&
-        this.getPiece(i, j) == V.SILVER_G
-      ) {
-        return true;
-      }
-    }
-    return false;
+    return this.isAttackedBySlideNJump(
+      sq, color, V.SILVER, V.steps[V.BISHOP].concat([ [shift, 0] ]), 1);
   }
 
-  isAttackedByPawn([x, y], color) {
+  isAttackedByPawn(sq, color) {
     const shift = (color == 'w' ? 1 : -1);
-    const [i, j] = [x + shift, y];
-    return (
-      V.OnBoard(i, j) &&
-      this.board[i][j] != V.EMPTY &&
-      this.getColor(i, j) == color &&
-      this.getPiece(i, j) == V.PAWN
-    );
+    return this.isAttackedBySlideNJump(sq, color, V.PAWN, [ [shift, 0] ], 1);
   }
 
   isAttackedByKnight(sq, color) {
     const forward = (color == 'w' ? 2 : -2);
     return this.isAttackedBySlideNJump(
-      sq, color, V.KNIGHT, [[forward, 1], [forward, -1]], "oneStep");
+      sq, color, V.KNIGHT, [ [forward, 1], [forward, -1] ], 1);
   }
 
   isAttackedByLance(sq, color) {
@@ -528,16 +515,14 @@ export class ShogiRules extends ChessRules {
   isAttackedByDragon(sq, color) {
     return (
       this.isAttackedBySlideNJump(sq, color, V.P_ROOK, V.steps[V.ROOK]) ||
-      this.isAttackedBySlideNJump(
-        sq, color, V.P_ROOK, V.steps[V.BISHOP], "oneStep")
+      this.isAttackedBySlideNJump(sq, color, V.P_ROOK, V.steps[V.BISHOP], 1)
     );
   }
 
   isAttackedByHorse(sq, color) {
     return (
       this.isAttackedBySlideNJump(sq, color, V.P_BISHOP, V.steps[V.BISHOP]) ||
-      this.isAttackedBySlideNJump(
-        sq, color, V.P_BISHOP, V.steps[V.ROOK], "oneStep")
+      this.isAttackedBySlideNJump(sq, color, V.P_BISHOP, V.steps[V.ROOK], 1)
     );
   }
 
@@ -552,14 +537,16 @@ export class ShogiRules extends ChessRules {
     return this.filterValid(moves);
   }
 
-  atLeastOneMove() {
+  atLeastOneMove(noReserve) {
     if (!super.atLeastOneMove()) {
-      // Search one reserve move
-      for (let i = 0; i < V.RESERVE_PIECES.length; i++) {
-        let moves = this.filterValid(
-          this.getReserveMoves([V.size.x + (this.turn == "w" ? 0 : 1), i])
-        );
-        if (moves.length > 0) return true;
+      if (!noReserve) {
+        // Search one reserve move
+        for (let i = 0; i < V.RESERVE_PIECES.length; i++) {
+          let moves = this.filterValid(
+            this.getReserveMoves([V.size.x + (this.turn == "w" ? 0 : 1), i])
+          );
+          if (moves.length > 0) return true;
+        }
       }
       return false;
     }