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