A few bug fixes
[vchess.git] / client / src / variants / Forward.js
1 import { ChessRules } from "@/base_rules";
2
3 export class ForwardRules extends ChessRules {
4
5 static get PawnSpecs() {
6 return Object.assign(
7 {},
8 ChessRules.PawnSpecs,
9 {
10 bidirectional: true,
11 captureBackward: true,
12 promotions: [V.PAWN]
13 }
14 );
15 }
16
17 static get PROMOTED() {
18 return ['s', 'u', 'o', 'c', 't', 'l'];
19 }
20
21 static get PIECES() {
22 return ChessRules.PIECES.concat(V.PROMOTED);
23 }
24
25 getPpath(b) {
26 return (V.PROMOTED.includes(b[1]) ? "Forward/" : "") + b;
27 }
28
29 scanKings(fen) {
30 // Squares of white and black king:
31 this.kingPos = { w: [-1, -1], b: [-1, -1] };
32 const fenRows = V.ParseFen(fen).position.split("/");
33 const startRow = { 'w': V.size.x - 1, 'b': 0 };
34 for (let i = 0; i < fenRows.length; i++) {
35 let k = 0; //column index on board
36 for (let j = 0; j < fenRows[i].length; j++) {
37 switch (fenRows[i].charAt(j)) {
38 case "k":
39 case "l":
40 this.kingPos["b"] = [i, k];
41 break;
42 case "K":
43 case "L":
44 this.kingPos["w"] = [i, k];
45 break;
46 default: {
47 const num = parseInt(fenRows[i].charAt(j), 10);
48 if (!isNaN(num)) k += num - 1;
49 }
50 }
51 k++;
52 }
53 }
54 }
55
56 getPotentialMovesFrom(sq) {
57 const piece = this.getPiece(sq[0], sq[1]);
58 if (V.PROMOTED.includes(piece)) {
59 switch (piece) {
60 case 's':
61 return (
62 super.getPotentialPawnMoves(sq)
63 // Promoted pawns back on initial rank don't jump 2 squares:
64 .filter(m => Math.abs(m.end.x - m.start.x) == 1)
65 );
66 case 'u': return super.getPotentialRookMoves(sq);
67 case 'o': return super.getPotentialKnightMoves(sq);
68 case 'c': return super.getPotentialBishopMoves(sq);
69 case 't': return super.getPotentialQueenMoves(sq);
70 case 'l': return super.getPotentialKingMoves(sq);
71 }
72 }
73 // Unpromoted piece: only go forward
74 const color = this.turn;
75 let moves =
76 super.getPotentialMovesFrom(sq)
77 .filter(m => {
78 const delta = m.end.x - m.start.x;
79 return ((color == 'w' && delta <= 0) || (color == 'b' && delta >= 0));
80 });
81 // Apply promotions:
82 const lastRank = (color == 'w' ? 0 : 7);
83 moves.forEach(m => {
84 if (m.end.x == lastRank) {
85 const pIdx = ChessRules.PIECES.findIndex(p => p == m.appear[0].p);
86 m.appear[0].p = V.PROMOTED[pIdx];
87 }
88 });
89 return moves;
90 }
91
92 isAttackedBySlideNJump([x, y], color, piece, steps, oneStep) {
93 const pIdx = ChessRules.PIECES.findIndex(p => p == piece);
94 const ppiece = V.PROMOTED[pIdx];
95 const forward = (color == 'w' ? -1 : 1);
96 for (let step of steps) {
97 let rx = x + step[0],
98 ry = y + step[1];
99 while (V.OnBoard(rx, ry) && this.board[rx][ry] == V.EMPTY && !oneStep) {
100 rx += step[0];
101 ry += step[1];
102 }
103 if (V.OnBoard(rx, ry) && this.getColor(rx, ry) == color) {
104 const pieceR = this.getPiece(rx, ry);
105 if (
106 pieceR == ppiece ||
107 (pieceR == piece && (step[0] == 0 || -step[0] == forward))
108 ) {
109 return true;
110 }
111 }
112 }
113 return false;
114 }
115
116 postPlay(move) {
117 super.postPlay(move);
118 if (move.appear[0].p == "l")
119 this.kingPos[move.appear[0].c] = [move.appear[0].x, move.appear[0].y];
120 }
121
122 postUndo(move) {
123 super.postUndo(move);
124 if (move.appear[0].p == "l")
125 this.kingPos[this.turn] = [move.start.x, move.start.y];
126 }
127
128 static get VALUES() {
129 return Object.assign(
130 {
131 s: 2,
132 u: 8,
133 o: 5,
134 c: 5,
135 t: 15,
136 l: 1500
137 },
138 ChessRules.VALUES
139 );
140 }
141
142 };