Draft Suction Chess
[vchess.git] / client / src / variants / Suction.js
1 import { ChessRules, PiPo, Move } from "@/base_rules";
2
3 export const VariantRules = class AntimatterRules extends ChessRules {
4 getBasicMove([sx, sy], [ex, ey]) {
5 const startColor = this.getColor(sx, sy);
6 const startPiece = this.getPiece(sx, sy);
7 let mv = new Move({
8 appear: [
9 new PiPo({
10 x: ex,
11 y: ey,
12 c: startColor,
13 p: startPiece
14 })
15 ],
16 vanish: [
17 new PiPo({
18 x: sx,
19 y: sy,
20 c: startColor,
21 p: startPiece
22 })
23 ]
24 });
25
26 if (this.board[ex][ey] != V.EMPTY) {
27 const endColor = this.getColor(ex, ey);
28 const endPiece = this.getPiece(ex, ey);
29 mv.vanish.push(
30 new PiPo({
31 x: ex,
32 y: ey,
33 c: endColor,
34 p: endPiece
35 })
36 );
37 mv.appear.push(
38 new PiPo({
39 x: sx,
40 y: sy,
41 c: endColor,
42 p: endPiece
43 })
44 );
45 }
46 return mv;
47 }
48
49 getPotentialPawnMoves([x, y]) {
50 const color = this.turn;
51 let moves = [];
52 const [sizeX, sizeY] = [V.size.x, V.size.y];
53 const shiftX = color == "w" ? -1 : 1;
54 const startRank = color == "w" ? sizeX - 2 : 1;
55 const firstRank = color == "w" ? sizeX - 1 : 0;
56
57 if (x + shiftX >= 0 && x + shiftX < sizeX) {
58 // One square forward
59 if (this.board[x + shiftX][y] == V.EMPTY) {
60 moves.push(
61 this.getBasicMove([x, y], [x + shiftX, y], {
62 c: color,
63 p: "p"
64 })
65 );
66 if (
67 [startRank,firstRank].includes(x) &&
68 this.board[x + 2 * shiftX][y] == V.EMPTY
69 ) {
70 // Two squares jump
71 moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y]));
72 }
73 }
74 // Swaps
75 for (let shiftY of [-1, 1]) {
76 if (
77 y + shiftY >= 0 &&
78 y + shiftY < sizeY &&
79 this.board[x + shiftX][y + shiftY] != V.EMPTY &&
80 this.canTake([x, y], [x + shiftX, y + shiftY])
81 ) {
82 moves.push(
83 this.getBasicMove([x, y], [x + shiftX, y + shiftY], {
84 c: color,
85 p: "p"
86 })
87 );
88 }
89 }
90 }
91
92 // En passant
93 const Lep = this.epSquares.length;
94 const epSquare = this.epSquares[Lep - 1]; //always at least one element
95 if (
96 !!epSquare &&
97 epSquare.x == x + shiftX &&
98 Math.abs(epSquare.y - y) == 1
99 ) {
100 let enpassantMove = this.getBasicMove([x, y], [epSquare.x, epSquare.y]);
101 const oppCol = V.GetOppCol(color);
102 enpassantMove.vanish.push({
103 x: x,
104 y: epSquare.y,
105 p: "p",
106 c: oppCol
107 });
108 enpassantMove.appear.push({
109 x: x,
110 y: y,
111 p: "p",
112 c: oppCol
113 });
114 moves.push(enpassantMove);
115 }
116
117 return moves;
118 }
119
120 getPotentialKingMoves() {
121 return [];
122 }
123
124 updateVariables(move) {
125 super.updateVariables(move);
126 if (move.vanish.length == 2) {
127 // Was opponent king swapped?
128 if (move.vanish[1].p == V.KING)
129 this.kingPos[this.turn] = [move.appear[1].x, move.appear[1].y];
130 }
131 }
132
133 unupdateVariables(move) {
134 super.unupdateVariables(move);
135 if (move.appear.length == 2) {
136 // Was opponent king swapped?
137 if (move.appear[1].p == V.KING)
138 this.kingPos[move.vanish[1].c] = [move.vanish[1].x,move.vanish[1].y];
139 }
140 }
141
142 atLeastOneMove() {
143 return true;
144 }
145
146 filterValid(moves) {
147 return moves;
148 }
149
150 getCheckSquares() {
151 return [];
152 }
153
154 getCurrentScore() {
155 const color = this.turn;
156 const kp = this.kingPos[color];
157 if (color == "w" && kp[0] == 0)
158 return "0-1";
159 if (color == "b" && kp[0] == V.size.x - 1)
160 return "1-0";
161 // King is not on the opposite edge: game not over
162 return "*";
163 }
164
165 evalPosition() {
166 // Very simple criterion for now: kings position
167 return this.kingPos["w"][0] + this.kingPos["b"][0];
168 }
169 };