Commit | Line | Data |
---|---|---|
9bd6786b BA |
1 | import { ChessRules, PiPo, Move } from "@/base_rules"; |
2 | ||
32f6285e | 3 | export class BenedictRules extends ChessRules { |
7e8a7ea1 | 4 | |
9bd6786b BA |
5 | static get HasEnpassant() { |
6 | return false; | |
7 | } | |
8 | ||
32f6285e BA |
9 | static get PawnSpecs() { |
10 | return Object.assign( | |
11 | {}, | |
12 | ChessRules.PawnSpecs, | |
13 | { canCapture: false } | |
14 | ); | |
15 | } | |
16 | ||
9bd6786b BA |
17 | // TODO(?): some duplicated code in 2 next functions |
18 | getSlideNJumpMoves([x, y], steps, oneStep) { | |
19 | let moves = []; | |
20 | outerLoop: for (let loop = 0; loop < steps.length; loop++) { | |
21 | const step = steps[loop]; | |
22 | let i = x + step[0]; | |
23 | let j = y + step[1]; | |
24 | while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { | |
25 | moves.push(this.getBasicMove([x, y], [i, j])); | |
26 | if (oneStep) continue outerLoop; | |
27 | i += step[0]; | |
28 | j += step[1]; | |
29 | } | |
30 | // No capture check: handled elsewhere (next method) | |
31 | } | |
32 | return moves; | |
33 | } | |
34 | ||
35 | // Find possible captures from a square | |
36 | // follow steps from x,y until something is met. | |
37 | findCaptures([x, y]) { | |
38 | const color = this.getColor(x, y); | |
39 | const piece = this.getPiece(x, y); | |
40 | let squares = []; | |
41 | const steps = | |
42 | piece != V.PAWN | |
43 | ? [V.QUEEN,V.KING].includes(piece) | |
44 | ? V.steps[V.ROOK].concat(V.steps[V.BISHOP]) | |
45 | : V.steps[piece] | |
46 | : color == "w" | |
47 | ? [ | |
48 | [-1, -1], | |
49 | [-1, 1] | |
50 | ] | |
51 | : [ | |
52 | [1, -1], | |
53 | [1, 1] | |
54 | ]; | |
55 | const oneStep = [V.KNIGHT,V.PAWN,V.KING].includes(piece); | |
56 | outerLoop: for (let loop = 0; loop < steps.length; loop++) { | |
57 | const step = steps[loop]; | |
58 | let i = x + step[0]; | |
59 | let j = y + step[1]; | |
60 | while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { | |
61 | if (oneStep) continue outerLoop; | |
62 | i += step[0]; | |
63 | j += step[1]; | |
64 | } | |
65 | if ( | |
66 | V.OnBoard(i, j) && | |
67 | this.getColor(i, j) == V.GetOppCol(color) | |
68 | ) { | |
69 | // eat! | |
70 | squares.push([i, j]); | |
71 | } | |
72 | } | |
73 | return squares; | |
74 | } | |
75 | ||
9bd6786b BA |
76 | // TODO: appear/vanish description of a move is too verbose for Benedict. |
77 | // => Would need a new "flipped" array, to be passed in Game.vue... | |
78 | getPotentialMovesFrom([x, y]) { | |
79 | const color = this.turn; | |
80 | const oppCol = V.GetOppCol(color); | |
81 | // Get all moves from x,y without captures: | |
82 | let moves = super.getPotentialMovesFrom([x, y]); | |
83 | // Add flips: | |
84 | moves.forEach(m => { | |
2ceec0ec BA |
85 | let newAppear = []; |
86 | let newVanish = []; | |
9bd6786b | 87 | V.PlayOnBoard(this.board, m); |
bf7e5f36 BA |
88 | // If castling, m.appear has 2 elements. |
89 | // In this case, consider the attacks of moving units only. | |
90 | // (Sometimes the king or rook doesn't move). | |
91 | for (let i = 0; i < m.appear.length; i++) { | |
92 | const a = m.appear[i]; | |
93 | if (m.vanish[i].x != a.x || m.vanish[i].y != a.y) { | |
94 | const flipped = this.findCaptures([a.x, a.y]); | |
95 | flipped.forEach(sq => { | |
96 | const piece = this.getPiece(sq[0],sq[1]); | |
97 | const pipoA = new PiPo({ | |
98 | x:sq[0], | |
99 | y:sq[1], | |
100 | c:color, | |
101 | p:piece | |
102 | }); | |
103 | const pipoV = new PiPo({ | |
104 | x:sq[0], | |
105 | y:sq[1], | |
106 | c:oppCol, | |
107 | p:piece | |
108 | }); | |
109 | newAppear.push(pipoA); | |
110 | newVanish.push(pipoV); | |
1af00c56 | 111 | }); |
bf7e5f36 BA |
112 | } |
113 | } | |
2ceec0ec BA |
114 | Array.prototype.push.apply(m.appear, newAppear); |
115 | Array.prototype.push.apply(m.vanish, newVanish); | |
1af00c56 | 116 | V.UndoOnBoard(this.board, m); |
9bd6786b BA |
117 | }); |
118 | return moves; | |
119 | } | |
120 | ||
121 | // Moves cannot flip our king's color, so all are valid | |
122 | filterValid(moves) { | |
123 | return moves; | |
124 | } | |
125 | ||
32f6285e BA |
126 | // Since it's used just for the king, and there are no captures: |
127 | isAttacked(sq, color) { | |
128 | return false; | |
129 | } | |
130 | ||
9bd6786b BA |
131 | // No notion of check here: |
132 | getCheckSquares() { | |
133 | return []; | |
134 | } | |
135 | ||
1af00c56 BA |
136 | // Stop at the first move found |
137 | atLeastOneMove() { | |
138 | const color = this.turn; | |
1af00c56 BA |
139 | for (let i = 0; i < V.size.x; i++) { |
140 | for (let j = 0; j < V.size.y; j++) { | |
a930dd71 BA |
141 | if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) { |
142 | if (this.getPotentialMovesFrom([i, j]).length > 0) return true; | |
1af00c56 BA |
143 | } |
144 | } | |
145 | } | |
146 | return false; | |
147 | } | |
148 | ||
9bd6786b BA |
149 | getCurrentScore() { |
150 | const color = this.turn; | |
151 | // Did a king change color? | |
152 | const kp = this.kingPos[color]; | |
153 | if (this.getColor(kp[0], kp[1]) != color) | |
154 | return color == "w" ? "0-1" : "1-0"; | |
bb688df5 | 155 | if (this.atLeastOneMove()) return "*"; |
1af00c56 BA |
156 | // Stalemate: |
157 | return "1/2"; | |
9bd6786b | 158 | } |
57eb158f BA |
159 | |
160 | getNotation(move) { | |
161 | // Just remove flips: | |
162 | const basicMove = { | |
163 | appear: [move.appear[0]], | |
164 | vanish: [move.vanish[0]], | |
165 | start: move.start, | |
166 | end: move.end | |
167 | }; | |
168 | return super.getNotation(basicMove); | |
169 | } | |
7e8a7ea1 | 170 | |
9bd6786b | 171 | }; |