1 import { ChessRules
, PiPo
, Move
} from "@/base_rules";
3 export const VariantRules
= class SuctionRules
extends ChessRules
{
4 setOtherVariables(fen
) {
5 super.setOtherVariables(fen
);
6 // Local stack of captures
8 const cmove
= fen
.split(" ")[5];
9 if (cmove
== "-") this.cmoves
.push(null);
12 start: ChessRules
.SquareToCoords(cmove
.substr(0, 2)),
13 end: ChessRules
.SquareToCoords(cmove
.substr(2))
18 static IsGoodFen(fen
) {
19 if (!ChessRules
.IsGoodFen(fen
)) return false;
20 const fenParts
= fen
.split(" ");
21 if (fenParts
.length
!= 6) return false;
22 if (fenParts
[5] != "-" && !fenParts
[5].match(/^([a-h][1-8]){2}$/))
28 if (move.vanish
.length
== 2)
29 return { start: move.start
, end: move.end
};
33 getBasicMove([sx
, sy
], [ex
, ey
]) {
34 const startColor
= this.getColor(sx
, sy
);
35 const startPiece
= this.getPiece(sx
, sy
);
55 if (this.board
[ex
][ey
] != V
.EMPTY
) {
56 const endColor
= this.getColor(ex
, ey
);
57 const endPiece
= this.getPiece(ex
, ey
);
78 getPotentialPawnMoves([x
, y
]) {
79 const color
= this.turn
;
81 const [sizeX
, sizeY
] = [V
.size
.x
, V
.size
.y
];
82 const shiftX
= color
== "w" ? -1 : 1;
83 const startRank
= color
== "w" ? sizeX
- 2 : 1;
84 const firstRank
= color
== "w" ? sizeX
- 1 : 0;
86 if (x
+ shiftX
>= 0 && x
+ shiftX
< sizeX
) {
88 if (this.board
[x
+ shiftX
][y
] == V
.EMPTY
) {
90 this.getBasicMove([x
, y
], [x
+ shiftX
, y
], {
96 [startRank
,firstRank
].includes(x
) &&
97 this.board
[x
+ 2 * shiftX
][y
] == V
.EMPTY
100 moves
.push(this.getBasicMove([x
, y
], [x
+ 2 * shiftX
, y
]));
104 for (let shiftY
of [-1, 1]) {
107 y
+ shiftY
< sizeY
&&
108 this.board
[x
+ shiftX
][y
+ shiftY
] != V
.EMPTY
&&
109 this.canTake([x
, y
], [x
+ shiftX
, y
+ shiftY
])
112 this.getBasicMove([x
, y
], [x
+ shiftX
, y
+ shiftY
], {
122 const Lep
= this.epSquares
.length
;
123 const epSquare
= this.epSquares
[Lep
- 1]; //always at least one element
126 epSquare
.x
== x
+ shiftX
&&
127 Math
.abs(epSquare
.y
- y
) == 1
129 let enpassantMove
= this.getBasicMove([x
, y
], [epSquare
.x
, epSquare
.y
]);
130 const oppCol
= V
.GetOppCol(color
);
131 enpassantMove
.vanish
.push({
137 enpassantMove
.appear
.push({
143 moves
.push(enpassantMove
);
149 getPotentialKingMoves() {
153 // Does m2 un-do m1 ? (to disallow undoing captures)
154 oppositeMoves(m1
, m2
) {
157 m2
.vanish
.length
== 2 &&
158 m1
.start
.x
== m2
.start
.x
&&
159 m1
.end
.x
== m2
.end
.x
&&
160 m1
.start
.y
== m2
.start
.y
&&
166 if (moves
.length
== 0) return [];
167 const color
= this.turn
;
168 return moves
.filter(m
=> {
169 const L
= this.cmoves
.length
; //at least 1: init from FEN
170 return !this.oppositeMoves(this.cmoves
[L
- 1], m
);
174 updateVariables(move) {
175 super.updateVariables(move);
176 if (move.vanish
.length
== 2) {
177 // Was opponent king swapped?
178 if (move.vanish
[1].p
== V
.KING
)
179 this.kingPos
[this.turn
] = [move.appear
[1].x
, move.appear
[1].y
];
183 unupdateVariables(move) {
184 super.unupdateVariables(move);
185 if (move.appear
.length
== 2) {
186 // Was opponent king swapped?
187 if (move.appear
[1].p
== V
.KING
)
188 this.kingPos
[move.vanish
[1].c
] = [move.vanish
[1].x
,move.vanish
[1].y
];
192 static GenRandInitFen(randomness
) {
194 return ChessRules
.GenRandInitFen(randomness
) + " -";
198 const L
= this.cmoves
.length
;
199 const cmoveFen
= !this.cmoves
[L
- 1]
201 : ChessRules
.CoordsToSquare(this.cmoves
[L
- 1].start
) +
202 ChessRules
.CoordsToSquare(this.cmoves
[L
- 1].end
);
203 return super.getFen() + " " + cmoveFen
;
207 this.cmoves
.push(this.getCmove(move));
225 const color
= this.turn
;
226 const kp
= this.kingPos
[color
];
227 if (color
== "w" && kp
[0] == 0)
229 if (color
== "b" && kp
[0] == V
.size
.x
- 1)
231 // King is not on the opposite edge: game not over
236 // Very simple criterion for now: kings position
237 return this.kingPos
["w"][0] + this.kingPos
["b"][0];
241 // Translate final square
242 const finalSquare
= V
.CoordsToSquare(move.end
);
244 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
245 if (piece
== V
.PAWN
) {
248 if (move.vanish
.length
== 2) {
250 const startColumn
= V
.CoordToColumn(move.start
.y
);
251 notation
= startColumn
+ "x" + finalSquare
;
253 else notation
= finalSquare
;
258 piece
.toUpperCase() +
259 (move.vanish
.length
== 2 ? "x" : "") +