First draft of Shinobi (unworking)
[vchess.git] / client / src / variants / Copycat.js
CommitLineData
b21e0e3a
BA
1import { ChessRules } from "@/base_rules";
2
3export 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;
11 const oneStep = (piece == V.PAWN);
12 let movements = {},
13 steps = [];
14 if (piece == V.QUEEN) steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
15 else steps = V.steps[piece];
16 steps.forEach(s => {
17 let [i, j] = [x + s[0], y + s[1]];
18 while (
19 V.OnBoard(i, j) &&
20 this.board[i][j] == V.EMPTY &&
21 piece != V.KNIGHT
22 ) {
23 i += s[0];
24 j += s[1];
25 }
26 if (V.OnBoard(i, j) && this.getColor(i, j) == color) {
27 const attacked = this.getPiece(i, j);
28 if ([V.ROOK, V.BISHOP, V.KNIGHT].includes(attacked)) {
29 if (!movements[attacked]) movements[attacked] = true;
30 }
31 else if (attacked == V.QUEEN) {
32 if (!movements[V.ROOK]) movements[V.ROOK] = true;
33 if (!movements[V.BISHOP]) movements[V.BISHOP] = true;
34 }
35 }
36 });
37 Object.keys(movements).forEach(type => {
38 if (
39 (piece != V.QUEEN && type != piece) ||
40 (piece == V.QUEEN && type == V.KNIGHT)
41 ) {
42 Array.prototype.push.apply(moves,
43 this.getSlideNJumpMoves([x, y], V.steps[type], type == V.KNIGHT));
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};