Add simple Dice chess 8x8
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 3 May 2020 22:19:22 +0000 (00:19 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 3 May 2020 22:19:22 +0000 (00:19 +0200)
client/src/translations/en.js
client/src/translations/es.js
client/src/translations/fr.js
client/src/translations/rules/Dice/en.pug [new file with mode: 0644]
client/src/translations/rules/Dice/es.pug [new file with mode: 0644]
client/src/translations/rules/Dice/fr.pug [new file with mode: 0644]
client/src/variants/Dice.js [new file with mode: 0644]
server/db/populate.sql

index f853e52..59d409b 100644 (file)
@@ -232,6 +232,7 @@ export const translations = {
   "Reposition pieces": "Reposition pieces",
   "Reuse pieces": "Reuse pieces",
   "Reverse captures": "Reverse captures",
   "Reposition pieces": "Reposition pieces",
   "Reuse pieces": "Reuse pieces",
   "Reverse captures": "Reverse captures",
+  "Roll the dice": "Roll the dice",
   "Rotating board": "Rotating board",
   "Run forward": "Run forward",
   "Score a goal": "Score a goal",
   "Rotating board": "Rotating board",
   "Run forward": "Run forward",
   "Score a goal": "Score a goal",
index 3243f92..e702b32 100644 (file)
@@ -232,6 +232,7 @@ export const translations = {
   "Reposition pieces": "Reposicionar las piezas",
   "Reuse pieces": "Reutilizar piezas",
   "Reverse captures": "Capturas invertidas",
   "Reposition pieces": "Reposicionar las piezas",
   "Reuse pieces": "Reutilizar piezas",
   "Reverse captures": "Capturas invertidas",
+  "Roll the dice": "Tirar los dados",
   "Rotating board": "Tablero giratorio",
   "Run forward": "Correr hacia adelante",
   "Score a goal": "Marcar una meta",
   "Rotating board": "Tablero giratorio",
   "Run forward": "Correr hacia adelante",
   "Score a goal": "Marcar una meta",
index 483f34c..980742a 100644 (file)
@@ -232,6 +232,7 @@ export const translations = {
   "Reposition pieces": "Replacer les pièces",
   "Reuse pieces": "Réutiliser les pièces",
   "Reverse captures": "Captures inversées",
   "Reposition pieces": "Replacer les pièces",
   "Reuse pieces": "Réutiliser les pièces",
   "Reverse captures": "Captures inversées",
+  "Roll the dice": "Lancez le dé",
   "Rotating board": "Échiquier tournant",
   "Run forward": "Courir vers l'avant",
   "Score a goal": "Marquer un but",
   "Rotating board": "Échiquier tournant",
   "Run forward": "Courir vers l'avant",
   "Score a goal": "Marquer un but",
diff --git a/client/src/translations/rules/Dice/en.pug b/client/src/translations/rules/Dice/en.pug
new file mode 100644 (file)
index 0000000..3fc2354
--- /dev/null
@@ -0,0 +1,18 @@
+p.boxed.
+  Play the piece type determined by a dice roll.
+
+p.
+  At each turn, click on any empty square first: you will see a piece type
+  written in the moves list, and a piece of this nature will be highlighted on
+  the board. You then have to play a move with this piece's type.
+
+p There is no check or checkmate: the goal is to capture the king.
+
+figure.diagram-container
+  .diagram
+    | fen:r1b2b1r/pp2p3/2p2q2/3p1kpp/1P2Qp2/2K2P1P/P1PP2P1/RNB2BNR:
+  figcaption Both kings could be captured if the dice indicated a queen.
+
+p.
+  Games are likely to be very random with this constraint.
+  Play at your own risk :)
diff --git a/client/src/translations/rules/Dice/es.pug b/client/src/translations/rules/Dice/es.pug
new file mode 100644 (file)
index 0000000..4a08a92
--- /dev/null
@@ -0,0 +1,19 @@
+p.boxed.
+  Juega la pieza cuyo tipo está determinado por una tirada de dado.
+
+p.
+  En cada turno, haga clic en una casilla vacía: verá un tipo de pieza
+  escrito en la lista de jugadas, y se indicará una pieza de esta naturaleza
+  en el tablero. Luego debes jugar un movimiento con una pieza de este tipo.
+
+p No hay jaque ni jaque mate: el objetivo es capturar al rey.
+
+figure.diagram-container
+  .diagram
+    | fen:r1b2b1r/pp2p3/2p2q2/3p1kpp/1P2Qp2/2K2P1P/P1PP2P1/RNB2BNR:
+  figcaption.
+    Los dos reyes podrían ser capturados si el dado indica una dama.
+
+p.
+  Es probable que los juegos sean muy aleatorios con esta restricción.
+  Juega bajo tu propio riesgo :)
diff --git a/client/src/translations/rules/Dice/fr.pug b/client/src/translations/rules/Dice/fr.pug
new file mode 100644 (file)
index 0000000..42ee7ca
--- /dev/null
@@ -0,0 +1,19 @@
+p.boxed.
+  Jouez la pièce dont le type est déterminé par un lancer de dé.
+
+p.
+  À chaque tour, cliquez sur une case vide : vous verrez un type de pièce
+  écrit dans la liste des coups, et une pièce de cette nature sera indiquée
+  sur l'échiquier. Vous devez ensuite jouer un coup avec une pièce de ce type.
+
+p Il n'y a ni échec ni mat : l'objectif est de capturer le roi.
+
+figure.diagram-container
+  .diagram
+    | fen:r1b2b1r/pp2p3/2p2q2/3p1kpp/1P2Qp2/2K2P1P/P1PP2P1/RNB2BNR:
+  figcaption.
+    Les deux rois pourraient être capturés si le dé indiquait une dame.
+
+p.
+  Les parties sont susceptibles d'être très aléatoires avec cette contrainte.
+  Jouez à vos risques et périls :)
diff --git a/client/src/variants/Dice.js b/client/src/variants/Dice.js
new file mode 100644 (file)
index 0000000..a8ecf1b
--- /dev/null
@@ -0,0 +1,140 @@
+import { ChessRules, Move } from "@/base_rules";
+import { randInt } from "@/utils/alea";
+
+export class DiceRules extends ChessRules {
+  static get CanAnalyze() {
+    return true;//false;
+  }
+
+  doClick(square) {
+    if (
+      this.subTurn == 2 ||
+      isNaN(square[0]) ||
+      this.board[square[0]][square[1]] != V.EMPTY
+    ) {
+      return null;
+    }
+    // Announce the piece' type to be played:
+    return this.getRandPieceMove();
+  }
+
+  getPotentialMovesFrom([x, y]) {
+    const L = this.p2play.length;
+    if (
+      this.subTurn == 1 ||
+      // The piece type must match last p2play
+      this.getPiece(x, y) != this.p2play[L-1]
+    ) {
+      return [];
+    }
+    return super.getPotentialMovesFrom([x, y]);
+  }
+
+  setOtherVariables(fen) {
+    super.setOtherVariables(fen);
+    this.p2play = [];
+    this.subTurn = 1;
+  }
+
+  filterValid(moves) {
+    return moves;
+  }
+
+  getCheckSquares() {
+    return [];
+  }
+
+  getCurrentScore() {
+    const color = this.turn;
+    if (this.kingPos[color][0] < 0) return (color == 'w' ? "0-1" : "1-0");
+    return "*";
+  }
+
+  play(move) {
+    if (this.subTurn == 1) {
+      this.subTurn = 2;
+      this.p2play.push(move.appear[0].p);
+      return;
+    }
+    // Subturn == 2 means the (dice-constrained) move is played
+    move.flags = JSON.stringify(this.aggregateFlags());
+    V.PlayOnBoard(this.board, move);
+    this.epSquares.push(this.getEpSquare(move));
+    this.movesCount++;
+    this.turn = V.GetOppCol(this.turn);
+    this.subTurn = 1;
+    this.postPlay(move);
+  }
+
+  postPlay(move) {
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[move.vanish[1].c] = [-1, -1];
+    // Castle flags for captured king won't be updated (not important...)
+    super.postPlay(move);
+  }
+
+  undo(move) {
+    if (this.subTurn == 2) {
+      this.subTurn = 1;
+      this.p2play.pop();
+      return;
+    }
+    this.disaggregateFlags(JSON.parse(move.flags));
+    V.UndoOnBoard(this.board, move);
+    this.epSquares.pop();
+    this.movesCount--;
+    this.turn = V.GetOppCol(this.turn);
+    this.subTurn = 2;
+    this.postUndo(move);
+  }
+
+  postUndo(move) {
+    if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
+      this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
+    super.postUndo(move);
+  }
+
+  getRandPieceMove() {
+    // For current turn, find pieces which can move and roll a dice
+    let canMove = {};
+    const color = this.turn;
+    for (let i=0; i<8; i++) {
+      for (let j=0; j<8; j++) {
+        if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
+          const piece = this.getPiece(i, j);
+          if (
+            !canMove[piece] &&
+            super.getPotentialMovesFrom([i, j]).length > 0
+          ) {
+            canMove[piece] = [i, j];
+          }
+        }
+      }
+    }
+    const options = Object.keys(canMove);
+    const randPiece = options[randInt(options.length)];
+    return (
+      new Move({
+        appear: [{ p: randPiece }],
+        vanish: [],
+        start: { x: -1, y: -1 },
+        end: { x: canMove[randPiece][0], y: canMove[randPiece][1] }
+      })
+    );
+  }
+
+  // Random mover
+  getComputerMove() {
+    const toPlay = this.getRandPieceMove();
+    this.play(toPlay);
+    const moves = this.getAllValidMoves();
+    const choice = moves[randInt(moves.length)];
+    this.undo(toPlay);
+    return [toPlay, choice];
+  }
+
+  getNotation(move) {
+    if (this.subTurn == 1) return move.appear[0].p.toUpperCase();
+    return super.getNotation(move);
+  }
+};
index 9b55c86..a4b2b9a 100644 (file)
@@ -4,6 +4,7 @@ insert or ignore into Variants (name, description, noProblems) values
   ('Apocalypse', 'The end of the world', true),
   ('Chakart', 'Capture the princess', true),
   ('Dark', 'In the shadow', true),
   ('Apocalypse', 'The end of the world', true),
   ('Chakart', 'Capture the princess', true),
   ('Dark', 'In the shadow', true),
+  ('Dice', 'Roll the dice', true),
   ('Hidden', 'Unidentified pieces', true),
   ('Hiddenqueen', 'Queen disguised as a pawn', true),
   ('Synchrone', 'Play at the same time', true);
   ('Hidden', 'Unidentified pieces', true),
   ('Hiddenqueen', 'Queen disguised as a pawn', true),
   ('Synchrone', 'Play at the same time', true);