1 import { ChessRules
} from "@/base_rules";
3 export class CopycatRules
extends ChessRules
{
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
);
14 if (piece
== V
.QUEEN
) steps
= V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]);
15 else steps
= V
.steps
[piece
];
17 let [i
, j
] = [x
+ s
[0], y
+ s
[1]];
20 this.board
[i
][j
] == V
.EMPTY
&&
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;
31 else if (attacked
== V
.QUEEN
) {
32 if (!movements
[V
.ROOK
]) movements
[V
.ROOK
] = true;
33 if (!movements
[V
.BISHOP
]) movements
[V
.BISHOP
] = true;
37 Object
.keys(movements
).forEach(type
=> {
39 (piece
!= V
.QUEEN
&& type
!= piece
) ||
40 (piece
== V
.QUEEN
&& type
== V
.KNIGHT
)
42 Array
.prototype.push
.apply(moves
,
43 this.getSlideNJumpMoves([x
, y
], V
.steps
[type
], type
== V
.KNIGHT
));
49 // Detect indirect attacks:
51 [x
, y
], color
, steps1
, oneStep1
, piece1
, steps2
, oneStep2
, pieces2
)
53 for (let s1
of steps1
) {
56 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
&& !oneStep1
) {
62 this.board
[i
][j
] != V
.EMPTY
&&
63 this.getPiece(i
, j
) == piece1
&&
64 this.getColor(i
, j
) == color
66 // Continue to detect "copycat" attacks
67 for (let s2
of steps2
) {
72 this.board
[ii
][jj
] == V
.EMPTY
&&
80 this.board
[ii
][jj
] != V
.EMPTY
&&
81 pieces2
.includes(this.getPiece(ii
, jj
)) &&
82 this.getColor(ii
, jj
) == color
92 isAttackedByKnight(sq
, color
) {
93 if (super.isAttackedByKnight(sq
, color
)) return true;
95 this.isAttackedBy_aux(sq
, color
,
96 V
.steps
[V
.ROOK
], false, V
.KNIGHT
,
97 V
.steps
[V
.KNIGHT
], true, [V
.ROOK
, V
.QUEEN
]
99 this.isAttackedBy_aux(sq
, color
,
100 V
.steps
[V
.BISHOP
], false, V
.KNIGHT
,
101 V
.steps
[V
.KNIGHT
], true, [V
.BISHOP
, V
.QUEEN
]
106 isAttackedByRook(sq
, color
) {
107 if (super.isAttackedByRook(sq
, color
)) return true;
109 this.isAttackedBy_aux(sq
, color
,
110 V
.steps
[V
.KNIGHT
], true, V
.ROOK
,
111 V
.steps
[V
.ROOK
], false, [V
.KNIGHT
]
113 this.isAttackedBy_aux(sq
, color
,
114 V
.steps
[V
.BISHOP
], false, V
.ROOK
,
115 V
.steps
[V
.ROOK
], false, [V
.BISHOP
, V
.QUEEN
]
120 isAttackedByBishop(sq
, color
) {
121 if (super.isAttackedByBishop(sq
, color
)) return true;
123 this.isAttackedBy_aux(sq
, color
,
124 V
.steps
[V
.KNIGHT
], true, V
.BISHOP
,
125 V
.steps
[V
.BISHOP
], false, [V
.KNIGHT
]
127 this.isAttackedBy_aux(sq
, color
,
128 V
.steps
[V
.ROOK
], false, V
.BISHOP
,
129 V
.steps
[V
.BISHOP
], false, [V
.ROOK
, V
.QUEEN
]
134 isAttackedByQueen(sq
, color
) {
135 if (super.isAttackedByQueen(sq
, color
)) return true;
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
]
144 static get SEARCH_DEPTH() {