Commit | Line | Data |
---|---|---|
68971030 BA |
1 | import { ChessRules, Move } from "@/base_rules"; |
2 | import { randInt } from "@/utils/alea"; | |
3 | ||
4 | export class DiceRules extends ChessRules { | |
7e8a7ea1 | 5 | |
74afb57d BA |
6 | static get Options() { |
7 | return { | |
8 | select: [ | |
9 | { | |
10 | label: "Randomness", | |
11 | variable: "randomness", | |
12 | defaut: 2, | |
13 | options: [ | |
14 | { label: "Deterministic", value: 0 }, | |
15 | { label: "Symmetric random", value: 1 }, | |
16 | { label: "Asymmetric random", value: 2 } | |
17 | ] | |
18 | } | |
19 | ] | |
20 | }; | |
21 | } | |
22 | ||
68971030 | 23 | static get CanAnalyze() { |
0ada7ac5 | 24 | return false; |
68971030 BA |
25 | } |
26 | ||
6e0f2842 BA |
27 | static ParseFen(fen) { |
28 | const fenParts = fen.split(" "); | |
29 | return Object.assign( | |
30 | ChessRules.ParseFen(fen), | |
31 | { toplay: fenParts[5] } | |
32 | ); | |
68971030 BA |
33 | } |
34 | ||
6e0f2842 BA |
35 | setOtherVariables(fen) { |
36 | super.setOtherVariables(fen); | |
37 | this.p2play = []; | |
38 | const toplay = V.ParseFen(fen).toplay; | |
39 | if (toplay != "-") this.p2play.push(toplay); | |
40 | } | |
41 | ||
42 | getFen() { | |
43 | return super.getFen() + " " + this.getToplayFen(); | |
44 | } | |
45 | ||
c98f15e7 | 46 | getFenForRepeat() { |
6e0f2842 BA |
47 | return super.getFenForRepeat() + "_" + this.getToplayFen(); |
48 | } | |
49 | ||
50 | getToplayFen() { | |
68971030 | 51 | const L = this.p2play.length; |
6e0f2842 BA |
52 | return (L > 0 ? this.p2play[L-1] : "-"); |
53 | } | |
54 | ||
4313762d BA |
55 | static GenRandInitFen(options) { |
56 | return ChessRules.GenRandInitFen(options) + " -"; | |
6e0f2842 BA |
57 | } |
58 | ||
59 | canMove(piece, color, [x, y]) { | |
60 | const oppCol = V.GetOppCol(color); | |
61 | if (piece == V.PAWN) { | |
0ada7ac5 | 62 | const forward = (color == 'w' ? -1 : 1); |
6e0f2842 | 63 | if (this.board[x + forward][y] == V.EMPTY) return true; |
0ada7ac5 BA |
64 | for (let shift of [-1, 1]) { |
65 | const [i, j] = [x + forward, y + shift]; | |
66 | if ( | |
67 | V.OnBoard(i, j) && | |
68 | this.board[i][j] != V.EMPTY && | |
6e0f2842 | 69 | this.getColor(i, j) == oppCol |
0ada7ac5 | 70 | ) { |
6e0f2842 BA |
71 | return true; |
72 | } | |
73 | } | |
74 | } | |
75 | else { | |
76 | const steps = | |
77 | [V.KING, V.QUEEN].includes(piece) | |
78 | ? V.steps[V.ROOK].concat(V.steps[V.BISHOP]) | |
79 | : V.steps[piece]; | |
80 | for (let s of steps) { | |
81 | const [i, j] = [x + s[0], y + s[1]]; | |
82 | if ( | |
83 | V.OnBoard(i, j) && | |
84 | (this.board[i][j] == V.EMPTY || this.getColor(i, j) == oppCol) | |
85 | ) { | |
86 | return true; | |
87 | } | |
88 | } | |
89 | } | |
90 | return false; | |
91 | } | |
92 | ||
93 | getRandPiece(color) { | |
94 | // Find pieces which can move and roll a dice | |
95 | let canMove = {}; | |
96 | for (let i=0; i<8; i++) { | |
97 | for (let j=0; j<8; j++) { | |
98 | if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) { | |
99 | const piece = this.getPiece(i, j); | |
100 | if (!canMove[piece] && this.canMove(piece, color, [i, j])) | |
101 | canMove[piece] = [i, j]; | |
102 | } | |
103 | } | |
104 | } | |
105 | const options = Object.keys(canMove); | |
106 | const randPiece = options[randInt(options.length)]; | |
107 | return [randPiece, canMove[randPiece]]; | |
108 | } | |
109 | ||
110 | getPotentialMovesFrom([x, y]) { | |
111 | const color = this.turn; | |
112 | let moves = undefined; | |
113 | if (this.movesCount == 0) moves = super.getPotentialMovesFrom([x, y]); | |
114 | else { | |
115 | const L = this.p2play.length; //L is >= 1 | |
116 | const piece = this.getPiece(x, y); | |
117 | if ( | |
118 | piece == V.PAWN && | |
119 | this.p2play[L-1] != V.PAWN && | |
120 | ((color == 'w' && x == 1) || (color == 'b' && x == 6)) | |
121 | ) { | |
122 | // The piece is a pawn about to promote | |
123 | const destX = (color == 'w' ? 0 : 7); | |
124 | moves = []; | |
125 | if (this.board[destX][y] == V.EMPTY) { | |
0ada7ac5 BA |
126 | moves.push( |
127 | this.getBasicMove( | |
6e0f2842 | 128 | [x, y], [destX, y], { c: color, p: this.p2play[L-1] }) |
0ada7ac5 BA |
129 | ); |
130 | } | |
6e0f2842 BA |
131 | for (let shift of [-1, 1]) { |
132 | const [i, j] = [destX, y + shift]; | |
133 | if ( | |
134 | V.OnBoard(i, j) && | |
135 | this.board[i][j] != V.EMPTY && | |
136 | this.getColor(i, j) != color | |
137 | ) { | |
138 | moves.push( | |
139 | this.getBasicMove( | |
140 | [x, y], [i, j], { c: color, p: this.p2play[L-1] }) | |
141 | ); | |
142 | } | |
143 | } | |
0ada7ac5 | 144 | } |
6e0f2842 BA |
145 | else if (piece != this.p2play[L-1]) |
146 | // The piece type must match last p2play | |
147 | return []; | |
148 | else moves = super.getPotentialMovesFrom([x, y]); | |
0ada7ac5 | 149 | } |
6e0f2842 BA |
150 | // Decide which piece the opponent will play: |
151 | const oppCol = V.GetOppCol(color); | |
152 | moves.forEach(m => { | |
153 | V.PlayOnBoard(this.board, m); | |
154 | const [piece, square] = this.getRandPiece(oppCol); | |
155 | m.start.toplay = square; | |
c98f15e7 | 156 | m.end.p = piece; |
6e0f2842 BA |
157 | V.UndoOnBoard(this.board, m); |
158 | }); | |
159 | return moves; | |
68971030 BA |
160 | } |
161 | ||
162 | filterValid(moves) { | |
163 | return moves; | |
164 | } | |
165 | ||
166 | getCheckSquares() { | |
167 | return []; | |
168 | } | |
169 | ||
170 | getCurrentScore() { | |
171 | const color = this.turn; | |
172 | if (this.kingPos[color][0] < 0) return (color == 'w' ? "0-1" : "1-0"); | |
173 | return "*"; | |
174 | } | |
175 | ||
68971030 | 176 | postPlay(move) { |
c98f15e7 | 177 | this.p2play.push(move.end.p); |
68971030 BA |
178 | if (move.vanish.length == 2 && move.vanish[1].p == V.KING) |
179 | this.kingPos[move.vanish[1].c] = [-1, -1]; | |
180 | // Castle flags for captured king won't be updated (not important...) | |
181 | super.postPlay(move); | |
182 | } | |
183 | ||
68971030 | 184 | postUndo(move) { |
6e0f2842 | 185 | this.p2play.pop(); |
68971030 BA |
186 | if (move.vanish.length == 2 && move.vanish[1].p == V.KING) |
187 | this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y]; | |
188 | super.postUndo(move); | |
189 | } | |
190 | ||
6e0f2842 BA |
191 | static get SEARCH_DEPTH() { |
192 | return 1; | |
68971030 BA |
193 | } |
194 | ||
195 | getNotation(move) { | |
c98f15e7 | 196 | return super.getNotation(move) + "/" + move.end.p.toUpperCase(); |
68971030 | 197 | } |
7e8a7ea1 | 198 | |
68971030 | 199 | }; |