Fix promotions in Pandemonium1
[vchess.git] / client / src / variants / Pandemonium1.js
1 import { Pandemonium2Rules } from "@/variants/Pandemonium2";
2
3 export class Pandemonium1Rules extends Pandemonium2Rules {
4
5 static get PawnSpecs() {
6 return Object.assign(
7 { },
8 Pandemonium2Rules.PawnSpecs,
9 { threeSquares: true }
10 );
11 }
12
13 static get size() {
14 return { x: 10, y: 10};
15 }
16
17 static IsGoodEnpassant(enpassant) {
18 if (enpassant != "-") {
19 const squares = enpassant.split(",");
20 if (squares.length > 2) return false;
21 for (let sq of squares) {
22 if (!sq.match(/[a-j0-9]/)) return false;
23 }
24 }
25 return true;
26 }
27
28 static GenRandInitFen(options) {
29 const baseFen = Pandemonium2Rules.GenRandInitFen(options)
30 return baseFen.substr(0, 22) + "91/91/" + baseFen.substr(22);
31 }
32
33 getEnpassantFen() {
34 const L = this.epSquares.length;
35 if (!this.epSquares[L - 1]) return "-"; //no en-passant
36 let res = "";
37 this.epSquares[L - 1].forEach(sq => {
38 res += V.CoordsToSquare(sq) + ",";
39 });
40 return res.slice(0, -1); //remove last comma
41 }
42
43 getEpSquare(moveOrSquare) {
44 if (!moveOrSquare) return undefined;
45 if (typeof moveOrSquare === "string") {
46 const square = moveOrSquare;
47 if (square == "-") return undefined;
48 let res = [];
49 square.split(",").forEach(sq => {
50 res.push(V.SquareToCoords(sq));
51 });
52 return res;
53 }
54 // Argument is a move:
55 const move = moveOrSquare;
56 const [sx, sy, ex] = [move.start.x, move.start.y, move.end.x];
57 if (this.getPiece(sx, sy) == V.PAWN && Math.abs(sx - ex) >= 2) {
58 const step = (ex - sx) / Math.abs(ex - sx);
59 let res = [{
60 x: sx + step,
61 y: sy
62 }];
63 if (sx + 2 * step != ex) {
64 // 3-squares jump
65 res.push({
66 x: sx + 2 * step,
67 y: sy
68 });
69 }
70 return res;
71 }
72 return undefined; //default
73 }
74
75 applyPromotions(moves, promoted) {
76 const lastRanks =
77 (this.turn == 'w' ? [0, 1] : [V.size.x - 1, V.size.x - 2]);
78 let promotions = [];
79 moves.forEach(m => {
80 if (lastRanks.includes(m.start.x) || lastRanks.includes(m.end.x)) {
81 let pMove = JSON.parse(JSON.stringify(m));
82 pMove.appear[0].p = promoted;
83 promotions.push(pMove);
84 }
85 });
86 Array.prototype.push.apply(moves, promotions);
87 }
88
89 addPawnMoves([x1, y1], [x2, y2], moves) {
90 const color = this.turn;
91 const lastRanks = (color == "w" ? [0, 1] : [V.size.x - 1, V.size.x - 2]);
92 if (!lastRanks.includes(x2)) {
93 moves.push(this.getBasicMove([x1, y1], [x2, y2]));
94 return;
95 }
96 let finalPieces = [V.GILDING];
97 if (x2 == lastRanks[1]) finalPieces.push(V.PAWN);
98 for (let piece of finalPieces) {
99 const tr = (piece != V.PAWN ? { c: color, p: piece } : null);
100 moves.push(this.getBasicMove([x1, y1], [x2, y2], tr));
101 }
102 }
103
104 getEnpassantCaptures([x, y], shiftX) {
105 const Lep = this.epSquares.length;
106 const epSquare = this.epSquares[Lep - 1];
107 let moves = [];
108 if (!!epSquare) {
109 for (let epsq of epSquare) {
110 // TODO: some redundant checks
111 if (epsq.x == x + shiftX && Math.abs(epsq.y - y) == 1) {
112 let enpassantMove = this.getBasicMove([x, y], [epsq.x, epsq.y]);
113 // WARNING: the captured pawn may be diagonally behind us,
114 // if it's a 3-squares jump and we take on 1st passing square
115 const px = this.board[x][epsq.y] != V.EMPTY ? x : x - shiftX;
116 enpassantMove.vanish.push({
117 x: px,
118 y: epsq.y,
119 p: "p",
120 c: this.getColor(px, epsq.y)
121 });
122 moves.push(enpassantMove);
123 }
124 }
125 }
126 return moves;
127 }
128
129 };