Code simplification + a few fixes
[vchess.git] / public / javascripts / variants / Crazyhouse.js
CommitLineData
a6abf094
BA
1class CrazyhouseRules extends ChessRules
2{
3 initVariables(fen)
4 {
1221ac47 5 super.initVariables(fen);
a6abf094 6 // Also init reserves (used by the interface to show landing pieces)
a6abf094
BA
7 this.reserve =
8 {
9 "w":
10 {
11 [V.PAWN]: 0,
12 [V.ROOK]: 0,
13 [V.KNIGHT]: 0,
14 [V.BISHOP]: 0,
15 [V.QUEEN]: 0,
16 },
17 "b":
18 {
19 [V.PAWN]: 0,
20 [V.ROOK]: 0,
21 [V.KNIGHT]: 0,
22 [V.BISHOP]: 0,
23 [V.QUEEN]: 0,
24 }
25 };
0b7d99ec 26 this.promoted = doubleArray(V.size.x, V.size.y, false);
6752407b
BA
27 // May be a continuation: adjust numbers of pieces in reserve + promoted pieces
28 this.moves.forEach(m => { this.updateVariables(m); });
5c42c64e
BA
29 }
30
31 getColor(i,j)
32 {
0b7d99ec
BA
33 if (i >= V.size.x)
34 return (i==V.size.x ? "w" : "b");
5c42c64e
BA
35 return this.board[i][j].charAt(0);
36 }
37 getPiece(i,j)
38 {
0b7d99ec
BA
39 if (i >= V.size.x)
40 return V.RESERVE_PIECES[j];
5c42c64e 41 return this.board[i][j].charAt(1);
a6abf094
BA
42 }
43
44 // Used by the interface:
1221ac47 45 getReservePpath(color, index)
a6abf094 46 {
0b7d99ec 47 return color + V.RESERVE_PIECES[index];
a6abf094
BA
48 }
49
92342261 50 // Ordering on reserve pieces
1221ac47 51 static get RESERVE_PIECES() {
1221ac47
BA
52 return [V.PAWN,V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
53 }
54
55 getReserveMoves([x,y])
a6abf094 56 {
a6abf094 57 const color = this.turn;
0b7d99ec 58 const p = V.RESERVE_PIECES[y];
1221ac47
BA
59 if (this.reserve[color][p] == 0)
60 return [];
61 let moves = [];
0b7d99ec
BA
62 const pawnShift = (p==V.PAWN ? 1 : 0);
63 for (let i=pawnShift; i<V.size.x-pawnShift; i++)
1221ac47 64 {
0b7d99ec 65 for (let j=0; j<V.size.y; j++)
1221ac47 66 {
0b7d99ec 67 if (this.board[i][j] == V.EMPTY)
1221ac47
BA
68 {
69 let mv = new Move({
70 appear: [
71 new PiPo({
72 x: i,
73 y: j,
74 c: color,
75 p: p
76 })
5c42c64e
BA
77 ],
78 vanish: [],
6752407b 79 start: {x:x, y:y}, //a bit artificial...
5c42c64e 80 end: {x:i, y:j}
1221ac47
BA
81 });
82 moves.push(mv);
83 }
84 }
85 }
a6abf094
BA
86 return moves;
87 }
88
1221ac47 89 getPotentialMovesFrom([x,y])
a6abf094 90 {
0b7d99ec 91 if (x >= V.size.x)
6752407b 92 {
92342261 93 // Reserves, outside of board: x == sizeX(+1)
6752407b
BA
94 return this.getReserveMoves([x,y]);
95 }
96 // Standard moves
97 return super.getPotentialMovesFrom([x,y]);
a6abf094
BA
98 }
99
a6abf094
BA
100 getAllValidMoves()
101 {
1221ac47
BA
102 let moves = super.getAllValidMoves();
103 const color = this.turn;
0b7d99ec
BA
104 for (let i=0; i<V.RESERVE_PIECES.length; i++)
105 moves = moves.concat(this.getReserveMoves([V.size.x+(color=="w"?0:1),i]));
1221ac47 106 return this.filterValid(moves);
a6abf094
BA
107 }
108
a6abf094
BA
109 atLeastOneMove()
110 {
1221ac47
BA
111 if (!super.atLeastOneMove())
112 {
0b7d99ec
BA
113 const color = this.turn;
114 // Search one reserve move
115 for (let i=0; i<V.RESERVE_PIECES.length; i++)
1221ac47 116 {
0b7d99ec
BA
117 let moves = this.filterValid(
118 this.getReserveMoves([V.size.x+(this.turn=="w"?0:1), i]) );
1221ac47
BA
119 if (moves.length > 0)
120 return true;
121 }
122 return false;
123 }
124 return true;
a6abf094
BA
125 }
126
a6abf094
BA
127 updateVariables(move)
128 {
1221ac47 129 super.updateVariables(move);
6752407b
BA
130 if (move.vanish.length == 2 && move.appear.length == 2)
131 return; //skip castle
1221ac47 132 const color = this.turn;
6752407b 133 if (move.vanish.length == 0)
6752407b 134 {
8a60cacd
BA
135 this.reserve[color][move.appear[0].p]--;
136 return;
6752407b 137 }
8a60cacd
BA
138 move.movePromoted = this.promoted[move.start.x][move.start.y];
139 move.capturePromoted = this.promoted[move.end.x][move.end.y]
140 this.promoted[move.start.x][move.start.y] = false;
141 this.promoted[move.end.x][move.end.y] = move.movePromoted
142 || (move.vanish[0].p == V.PAWN && move.appear[0].p != V.PAWN);
143 if (move.capturePromoted)
0b7d99ec 144 this.reserve[color][V.PAWN]++;
8a60cacd
BA
145 else if (move.vanish.length == 2)
146 this.reserve[color][move.vanish[1].p]++;
a6abf094 147 }
1221ac47 148
a6abf094
BA
149 unupdateVariables(move)
150 {
1221ac47 151 super.unupdateVariables(move);
8a60cacd
BA
152 if (move.vanish.length == 2 && move.appear.length == 2)
153 return;
1221ac47 154 const color = this.turn;
6752407b 155 if (move.vanish.length == 0)
6752407b 156 {
8a60cacd
BA
157 this.reserve[color][move.appear[0].p]++;
158 return;
6752407b 159 }
8a60cacd
BA
160 if (move.movePromoted)
161 this.promoted[move.start.x][move.start.y] = true;
162 this.promoted[move.end.x][move.end.y] = move.capturePromoted;
163 if (move.capturePromoted)
0b7d99ec 164 this.reserve[color][V.PAWN]--;
8a60cacd
BA
165 else if (move.vanish.length == 2)
166 this.reserve[color][move.vanish[1].p]--;
a6abf094
BA
167 }
168
169 static get SEARCH_DEPTH() { return 2; } //high branching factor
170
6752407b
BA
171 evalPosition()
172 {
173 let evaluation = super.evalPosition();
174 // Add reserves:
0b7d99ec 175 for (let i=0; i<V.RESERVE_PIECES.length; i++)
6752407b 176 {
0b7d99ec
BA
177 const p = V.RESERVE_PIECES[i];
178 evaluation += this.reserve["w"][p] * V.VALUES[p];
179 evaluation -= this.reserve["b"][p] * V.VALUES[p];
6752407b
BA
180 }
181 return evaluation;
182 }
183
a6abf094
BA
184 getNotation(move)
185 {
186 if (move.vanish.length > 0)
187 return super.getNotation(move);
188 // Rebirth:
189 const piece =
0b7d99ec 190 (move.appear[0].p != V.PAWN ? move.appear[0].p.toUpperCase() : "");
a6abf094 191 const finalSquare =
0b7d99ec 192 String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
a6abf094
BA
193 return piece + "@" + finalSquare;
194 }
6752407b
BA
195
196 getLongNotation(move)
197 {
198 if (move.vanish.length > 0)
199 return super.getLongNotation(move);
200 const finalSquare =
0b7d99ec 201 String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
6752407b
BA
202 return "@" + finalSquare;
203 }
a6abf094 204}