Add Cannibal variant
[vchess.git] / client / src / variants / Cannibal.js
1 import { ChessRules } from "@/base_rules";
2
3 export class CannibalRules extends ChessRules {
4 // Trim all non-capturing moves
5 static KeepCaptures(moves) {
6 return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1);
7 }
8
9 // Stop at the first capture found (if any)
10 atLeastOneCapture() {
11 const color = this.turn;
12 const oppCol = V.GetOppCol(color);
13 for (let i = 0; i < V.size.x; i++) {
14 for (let j = 0; j < V.size.y; j++) {
15 if (
16 this.board[i][j] != V.EMPTY &&
17 this.getColor(i, j) != oppCol &&
18 this.filterValid(this.getPotentialMovesFrom([i, j])).some(m =>
19 // Warning: discard castle moves
20 m.vanish.length == 2 && m.appear.length == 1)
21 ) {
22 return true;
23 }
24 }
25 }
26 return false;
27 }
28
29 getPotentialMovesFrom([x, y]) {
30 let moves = super.getPotentialMovesFrom([x, y]);
31 // Transform capturers, except for the king
32 moves.forEach(m => {
33 if (
34 m.appear[0].p != V.KING &&
35 m.vanish.length == 2 &&
36 m.appear.length == 1 &&
37 m.vanish[0].p != m.vanish[1].p
38 ) {
39 m.appear[0].p = m.vanish[1].p;
40 }
41 });
42 return moves;
43 }
44
45 getPossibleMovesFrom(sq) {
46 let moves = this.filterValid(this.getPotentialMovesFrom(sq));
47 const captureMoves = V.KeepCaptures(moves);
48 if (captureMoves.length > 0) return captureMoves;
49 if (this.atLeastOneCapture()) return [];
50 return moves;
51 }
52
53 getAllValidMoves() {
54 const moves = super.getAllValidMoves();
55 if (moves.some(m => m.vanish.length == 2)) return V.KeepCaptures(moves);
56 return moves;
57 }
58
59 static get SEARCH_DEPTH() {
60 return 4;
61 }
62 };