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