Add simple Dice chess 8x8
[vchess.git] / client / src / variants / Dice.js
1 import { ChessRules, Move } from "@/base_rules";
2 import { randInt } from "@/utils/alea";
3
4 export class DiceRules extends ChessRules {
5 static get CanAnalyze() {
6 return true;//false;
7 }
8
9 doClick(square) {
10 if (
11 this.subTurn == 2 ||
12 isNaN(square[0]) ||
13 this.board[square[0]][square[1]] != V.EMPTY
14 ) {
15 return null;
16 }
17 // Announce the piece' type to be played:
18 return this.getRandPieceMove();
19 }
20
21 getPotentialMovesFrom([x, y]) {
22 const L = this.p2play.length;
23 if (
24 this.subTurn == 1 ||
25 // The piece type must match last p2play
26 this.getPiece(x, y) != this.p2play[L-1]
27 ) {
28 return [];
29 }
30 return super.getPotentialMovesFrom([x, y]);
31 }
32
33 setOtherVariables(fen) {
34 super.setOtherVariables(fen);
35 this.p2play = [];
36 this.subTurn = 1;
37 }
38
39 filterValid(moves) {
40 return moves;
41 }
42
43 getCheckSquares() {
44 return [];
45 }
46
47 getCurrentScore() {
48 const color = this.turn;
49 if (this.kingPos[color][0] < 0) return (color == 'w' ? "0-1" : "1-0");
50 return "*";
51 }
52
53 play(move) {
54 if (this.subTurn == 1) {
55 this.subTurn = 2;
56 this.p2play.push(move.appear[0].p);
57 return;
58 }
59 // Subturn == 2 means the (dice-constrained) move is played
60 move.flags = JSON.stringify(this.aggregateFlags());
61 V.PlayOnBoard(this.board, move);
62 this.epSquares.push(this.getEpSquare(move));
63 this.movesCount++;
64 this.turn = V.GetOppCol(this.turn);
65 this.subTurn = 1;
66 this.postPlay(move);
67 }
68
69 postPlay(move) {
70 if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
71 this.kingPos[move.vanish[1].c] = [-1, -1];
72 // Castle flags for captured king won't be updated (not important...)
73 super.postPlay(move);
74 }
75
76 undo(move) {
77 if (this.subTurn == 2) {
78 this.subTurn = 1;
79 this.p2play.pop();
80 return;
81 }
82 this.disaggregateFlags(JSON.parse(move.flags));
83 V.UndoOnBoard(this.board, move);
84 this.epSquares.pop();
85 this.movesCount--;
86 this.turn = V.GetOppCol(this.turn);
87 this.subTurn = 2;
88 this.postUndo(move);
89 }
90
91 postUndo(move) {
92 if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
93 this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
94 super.postUndo(move);
95 }
96
97 getRandPieceMove() {
98 // For current turn, find pieces which can move and roll a dice
99 let canMove = {};
100 const color = this.turn;
101 for (let i=0; i<8; i++) {
102 for (let j=0; j<8; j++) {
103 if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
104 const piece = this.getPiece(i, j);
105 if (
106 !canMove[piece] &&
107 super.getPotentialMovesFrom([i, j]).length > 0
108 ) {
109 canMove[piece] = [i, j];
110 }
111 }
112 }
113 }
114 const options = Object.keys(canMove);
115 const randPiece = options[randInt(options.length)];
116 return (
117 new Move({
118 appear: [{ p: randPiece }],
119 vanish: [],
120 start: { x: -1, y: -1 },
121 end: { x: canMove[randPiece][0], y: canMove[randPiece][1] }
122 })
123 );
124 }
125
126 // Random mover
127 getComputerMove() {
128 const toPlay = this.getRandPieceMove();
129 this.play(toPlay);
130 const moves = this.getAllValidMoves();
131 const choice = moves[randInt(moves.length)];
132 this.undo(toPlay);
133 return [toPlay, choice];
134 }
135
136 getNotation(move) {
137 if (this.subTurn == 1) return move.appear[0].p.toUpperCase();
138 return super.getNotation(move);
139 }
140 };