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