Commit | Line | Data |
---|---|---|
0b8bd121 BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
3 | export 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: { | |
49 | const num = parseInt(fenRows[i].charAt(j)); | |
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 | }; |