Change castle flags. Eightpieces still not OK, but almost
[vchess.git] / client / src / variants / Suction.js
1 import { ChessRules, PiPo, Move } from "@/base_rules";
2
3 export const VariantRules = class SuctionRules extends ChessRules {
4 static get HasFlags() {
5 return false;
6 }
7
8 setOtherVariables(fen) {
9
10 console.log(fen);
11
12 super.setOtherVariables(fen);
13 // Local stack of "captures"
14 this.cmoves = [];
15 const cmove = V.ParseFen(fen).cmove;
16 if (cmove == "-") this.cmoves.push(null);
17 else {
18 this.cmoves.push({
19 start: ChessRules.SquareToCoords(cmove.substr(0, 2)),
20 end: ChessRules.SquareToCoords(cmove.substr(2))
21 });
22 }
23 }
24
25 static ParseFen(fen) {
26 return Object.assign({}, ChessRules.ParseFen(fen), {
27 cmove: fen.split(" ")[4]
28 });
29 }
30
31 static IsGoodFen(fen) {
32 if (!ChessRules.IsGoodFen(fen)) return false;
33 const fenParts = fen.split(" ");
34 if (fenParts.length != 6) return false;
35 if (fenParts[5] != "-" && !fenParts[5].match(/^([a-h][1-8]){2}$/))
36 return false;
37 return true;
38 }
39
40 getCmove(move) {
41 if (move.vanish.length == 2)
42 return { start: move.start, end: move.end };
43 return null;
44 }
45
46 getBasicMove([sx, sy], [ex, ey]) {
47 const startColor = this.getColor(sx, sy);
48 const startPiece = this.getPiece(sx, sy);
49 let mv = new Move({
50 appear: [
51 new PiPo({
52 x: ex,
53 y: ey,
54 c: startColor,
55 p: startPiece
56 })
57 ],
58 vanish: [
59 new PiPo({
60 x: sx,
61 y: sy,
62 c: startColor,
63 p: startPiece
64 })
65 ]
66 });
67
68 if (this.board[ex][ey] != V.EMPTY) {
69 const endColor = this.getColor(ex, ey);
70 const endPiece = this.getPiece(ex, ey);
71 mv.vanish.push(
72 new PiPo({
73 x: ex,
74 y: ey,
75 c: endColor,
76 p: endPiece
77 })
78 );
79 mv.appear.push(
80 new PiPo({
81 x: sx,
82 y: sy,
83 c: endColor,
84 p: endPiece
85 })
86 );
87 }
88 return mv;
89 }
90
91 getPotentialPawnMoves([x, y]) {
92 const color = this.turn;
93 let moves = [];
94 const [sizeX, sizeY] = [V.size.x, V.size.y];
95 const shiftX = color == "w" ? -1 : 1;
96 const startRank = color == "w" ? sizeX - 2 : 1;
97 const firstRank = color == "w" ? sizeX - 1 : 0;
98
99 if (x + shiftX >= 0 && x + shiftX < sizeX) {
100 // One square forward
101 if (this.board[x + shiftX][y] == V.EMPTY) {
102 moves.push(
103 this.getBasicMove([x, y], [x + shiftX, y], {
104 c: color,
105 p: "p"
106 })
107 );
108 if (
109 [startRank,firstRank].includes(x) &&
110 this.board[x + 2 * shiftX][y] == V.EMPTY
111 ) {
112 // Two squares jump
113 moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y]));
114 }
115 }
116 // Swaps
117 for (let shiftY of [-1, 1]) {
118 if (
119 y + shiftY >= 0 &&
120 y + shiftY < sizeY &&
121 this.board[x + shiftX][y + shiftY] != V.EMPTY &&
122 this.canTake([x, y], [x + shiftX, y + shiftY])
123 ) {
124 moves.push(
125 this.getBasicMove([x, y], [x + shiftX, y + shiftY], {
126 c: color,
127 p: "p"
128 })
129 );
130 }
131 }
132 }
133
134 // En passant
135 const Lep = this.epSquares.length;
136 const epSquare = this.epSquares[Lep - 1]; //always at least one element
137 if (
138 !!epSquare &&
139 epSquare.x == x + shiftX &&
140 Math.abs(epSquare.y - y) == 1
141 ) {
142 let enpassantMove = this.getBasicMove([x, y], [epSquare.x, epSquare.y]);
143 const oppCol = V.GetOppCol(color);
144 enpassantMove.vanish.push({
145 x: x,
146 y: epSquare.y,
147 p: "p",
148 c: oppCol
149 });
150 enpassantMove.appear.push({
151 x: x,
152 y: y,
153 p: "p",
154 c: oppCol
155 });
156 moves.push(enpassantMove);
157 }
158
159 return moves;
160 }
161
162 getPotentialKingMoves() {
163 return [];
164 }
165
166 // Does m2 un-do m1 ? (to disallow undoing captures)
167 oppositeMoves(m1, m2) {
168 return (
169 m1 &&
170 m2.vanish.length == 2 &&
171 m1.start.x == m2.start.x &&
172 m1.end.x == m2.end.x &&
173 m1.start.y == m2.start.y &&
174 m1.end.y == m2.end.y
175 );
176 }
177
178 filterValid(moves) {
179 if (moves.length == 0) return [];
180 const color = this.turn;
181 return moves.filter(m => {
182 const L = this.cmoves.length; //at least 1: init from FEN
183 return !this.oppositeMoves(this.cmoves[L - 1], m);
184 });
185 }
186
187 static GenRandInitFen(randomness) {
188 // Add empty cmove:
189 return ChessRules.GenRandInitFen(randomness).slice(0, -6) + "- -";
190 }
191
192 getFen() {
193 const L = this.cmoves.length;
194 const cmoveFen = !this.cmoves[L - 1]
195 ? "-"
196 : ChessRules.CoordsToSquare(this.cmoves[L - 1].start) +
197 ChessRules.CoordsToSquare(this.cmoves[L - 1].end);
198 return super.getFen() + " " + cmoveFen;
199 }
200
201 postPlay(move) {
202 super.postPlay(move);
203 if (move.vanish.length == 2) {
204 // Was opponent king swapped?
205 if (move.vanish[1].p == V.KING)
206 this.kingPos[this.turn] = [move.appear[1].x, move.appear[1].y];
207 }
208 this.cmoves.push(this.getCmove(move));
209 }
210
211 postUndo(move) {
212 super.postUndo(move);
213 if (move.appear.length == 2) {
214 if (move.appear[1].p == V.KING)
215 this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
216 }
217 this.cmoves.pop();
218 }
219
220 atLeastOneMove() {
221 return true;
222 }
223
224 getCheckSquares() {
225 return [];
226 }
227
228 getCurrentScore() {
229 const color = this.turn;
230 const kp = this.kingPos[color];
231 if (color == "w" && kp[0] == 0)
232 return "0-1";
233 if (color == "b" && kp[0] == V.size.x - 1)
234 return "1-0";
235 // King is not on the opposite edge: game not over
236 return "*";
237 }
238
239 evalPosition() {
240 // Very simple criterion for now: kings position
241 return this.kingPos["w"][0] + this.kingPos["b"][0];
242 }
243
244 getNotation(move) {
245 // Translate final square
246 const finalSquare = V.CoordsToSquare(move.end);
247
248 const piece = this.getPiece(move.start.x, move.start.y);
249 if (piece == V.PAWN) {
250 // Pawn move
251 let notation = "";
252 if (move.vanish.length == 2) {
253 // Capture
254 const startColumn = V.CoordToColumn(move.start.y);
255 notation = startColumn + "x" + finalSquare;
256 }
257 else notation = finalSquare;
258 return notation;
259 }
260 // Piece movement
261 return (
262 piece.toUpperCase() +
263 (move.vanish.length == 2 ? "x" : "") +
264 finalSquare
265 );
266 }
267 };