Commit | Line | Data |
---|---|---|
b21e0e3a BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
3 | export class CopycatRules extends ChessRules { | |
4 | ||
5 | getPotentialMovesFrom([x, y]) { | |
6 | let moves = super.getPotentialMovesFrom([x, y]); | |
7 | // Expand potential moves if attacking friendly pieces. | |
8 | const piece = this.getPiece(x,y); | |
9 | if ([V.PAWN, V.KING].includes(piece)) return moves; | |
10 | const color = this.turn; | |
b21e0e3a BA |
11 | let movements = {}, |
12 | steps = []; | |
13 | if (piece == V.QUEEN) steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); | |
14 | else steps = V.steps[piece]; | |
15 | steps.forEach(s => { | |
16 | let [i, j] = [x + s[0], y + s[1]]; | |
17 | while ( | |
18 | V.OnBoard(i, j) && | |
19 | this.board[i][j] == V.EMPTY && | |
20 | piece != V.KNIGHT | |
21 | ) { | |
22 | i += s[0]; | |
23 | j += s[1]; | |
24 | } | |
25 | if (V.OnBoard(i, j) && this.getColor(i, j) == color) { | |
26 | const attacked = this.getPiece(i, j); | |
27 | if ([V.ROOK, V.BISHOP, V.KNIGHT].includes(attacked)) { | |
28 | if (!movements[attacked]) movements[attacked] = true; | |
29 | } | |
30 | else if (attacked == V.QUEEN) { | |
31 | if (!movements[V.ROOK]) movements[V.ROOK] = true; | |
32 | if (!movements[V.BISHOP]) movements[V.BISHOP] = true; | |
33 | } | |
34 | } | |
35 | }); | |
36 | Object.keys(movements).forEach(type => { | |
37 | if ( | |
38 | (piece != V.QUEEN && type != piece) || | |
39 | (piece == V.QUEEN && type == V.KNIGHT) | |
40 | ) { | |
4313762d | 41 | const nbSteps = (type == V.KNIGHT ? 1 : undefined); |
b21e0e3a | 42 | Array.prototype.push.apply(moves, |
4313762d | 43 | super.getSlideNJumpMoves([x, y], V.steps[type], nbSteps)); |
b21e0e3a BA |
44 | } |
45 | }); | |
46 | return moves; | |
47 | } | |
48 | ||
49 | // Detect indirect attacks: | |
50 | isAttackedBy_aux( | |
51 | [x, y], color, steps1, oneStep1, piece1, steps2, oneStep2, pieces2) | |
52 | { | |
53 | for (let s1 of steps1) { | |
54 | let i = x + s1[0], | |
55 | j = y + s1[1]; | |
56 | while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY && !oneStep1) { | |
57 | i += s1[0]; | |
58 | j += s1[1]; | |
59 | } | |
60 | if ( | |
61 | V.OnBoard(i, j) && | |
62 | this.board[i][j] != V.EMPTY && | |
63 | this.getPiece(i, j) == piece1 && | |
64 | this.getColor(i, j) == color | |
65 | ) { | |
66 | // Continue to detect "copycat" attacks | |
67 | for (let s2 of steps2) { | |
68 | let ii = i + s2[0], | |
69 | jj = j + s2[1]; | |
70 | while ( | |
71 | V.OnBoard(ii, jj) && | |
72 | this.board[ii][jj] == V.EMPTY && | |
73 | !oneStep2 | |
74 | ) { | |
75 | ii += s2[0]; | |
76 | jj += s2[1]; | |
77 | } | |
78 | if ( | |
79 | V.OnBoard(ii, jj) && | |
80 | this.board[ii][jj] != V.EMPTY && | |
81 | pieces2.includes(this.getPiece(ii, jj)) && | |
82 | this.getColor(ii, jj) == color | |
83 | ) { | |
84 | return true; | |
85 | } | |
86 | } | |
87 | } | |
88 | } | |
89 | return false; | |
90 | } | |
91 | ||
92 | isAttackedByKnight(sq, color) { | |
93 | if (super.isAttackedByKnight(sq, color)) return true; | |
94 | return ( | |
95 | this.isAttackedBy_aux(sq, color, | |
96 | V.steps[V.ROOK], false, V.KNIGHT, | |
97 | V.steps[V.KNIGHT], true, [V.ROOK, V.QUEEN] | |
98 | ) || | |
99 | this.isAttackedBy_aux(sq, color, | |
100 | V.steps[V.BISHOP], false, V.KNIGHT, | |
101 | V.steps[V.KNIGHT], true, [V.BISHOP, V.QUEEN] | |
102 | ) | |
103 | ); | |
104 | } | |
105 | ||
106 | isAttackedByRook(sq, color) { | |
107 | if (super.isAttackedByRook(sq, color)) return true; | |
108 | return ( | |
109 | this.isAttackedBy_aux(sq, color, | |
110 | V.steps[V.KNIGHT], true, V.ROOK, | |
111 | V.steps[V.ROOK], false, [V.KNIGHT] | |
112 | ) || | |
113 | this.isAttackedBy_aux(sq, color, | |
114 | V.steps[V.BISHOP], false, V.ROOK, | |
115 | V.steps[V.ROOK], false, [V.BISHOP, V.QUEEN] | |
116 | ) | |
117 | ); | |
118 | } | |
119 | ||
120 | isAttackedByBishop(sq, color) { | |
121 | if (super.isAttackedByBishop(sq, color)) return true; | |
122 | return ( | |
123 | this.isAttackedBy_aux(sq, color, | |
124 | V.steps[V.KNIGHT], true, V.BISHOP, | |
125 | V.steps[V.BISHOP], false, [V.KNIGHT] | |
126 | ) || | |
127 | this.isAttackedBy_aux(sq, color, | |
128 | V.steps[V.ROOK], false, V.BISHOP, | |
129 | V.steps[V.BISHOP], false, [V.ROOK, V.QUEEN] | |
130 | ) | |
131 | ); | |
132 | } | |
133 | ||
134 | isAttackedByQueen(sq, color) { | |
135 | if (super.isAttackedByQueen(sq, color)) return true; | |
136 | return ( | |
137 | this.isAttackedBy_aux(sq, color, | |
138 | V.steps[V.KNIGHT], true, V.QUEEN, | |
139 | V.steps[V.ROOK].concat(V.steps[V.BISHOP]), false, [V.KNIGHT] | |
140 | ) | |
141 | ); | |
142 | } | |
143 | ||
269f9cfd BA |
144 | static get SEARCH_DEPTH() { |
145 | return 2; | |
146 | } | |
147 | ||
b21e0e3a | 148 | }; |