Rename Monochrome --> Monocolor , split Cannibal (forced captures or not)
[vchess.git] / client / src / variants / Cannibal2.js
1 import { ChessRules, Move, PiPo } from "@/base_rules";
2 import { Cannibal1Rules } from "@/variants/Cannibal1";
3
4 export class Cannibal2Rules extends Cannibal1Rules {
5
6 // Trim all non-capturing moves
7 static KeepCaptures(moves) {
8 return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1);
9 }
10
11 // Stop at the first capture found (if any)
12 atLeastOneCapture() {
13 const color = this.turn;
14 const oppCol = V.GetOppCol(color);
15 for (let i = 0; i < V.size.x; i++) {
16 for (let j = 0; j < V.size.y; j++) {
17 if (
18 this.board[i][j] != V.EMPTY &&
19 this.getColor(i, j) != oppCol &&
20 this.filterValid(this.getPotentialMovesFrom([i, j])).some(m =>
21 // Warning: discard castle moves
22 m.vanish.length == 2 && m.appear.length == 1)
23 ) {
24 return true;
25 }
26 }
27 }
28 return false;
29 }
30
31 addPawnMoves([x1, y1], [x2, y2], moves) {
32 let finalPieces = [V.PAWN];
33 const color = this.turn;
34 const lastRank = (color == "w" ? 0 : V.size.x - 1);
35 if (x2 == lastRank) {
36 if (this.board[x2][y2] != V.EMPTY)
37 // Cannibal rules: no choice if capture
38 finalPieces = [this.getPiece(x2, y2)];
39 else finalPieces = V.PawnSpecs.promotions;
40 }
41 let tr = null;
42 for (let piece of finalPieces) {
43 tr = (piece != V.PAWN ? { c: color, p: piece } : null);
44 moves.push(this.getBasicMove([x1, y1], [x2, y2], tr));
45 }
46 }
47
48 getPossibleMovesFrom(sq) {
49 let moves = this.filterValid(this.getPotentialMovesFrom(sq));
50 const captureMoves = V.KeepCaptures(moves);
51 if (captureMoves.length > 0) return captureMoves;
52 if (this.atLeastOneCapture()) return [];
53 return moves;
54 }
55
56 getAllValidMoves() {
57 const moves = super.getAllValidMoves();
58 if (moves.some(m => m.vanish.length == 2 && m.appear.length == 1))
59 return V.KeepCaptures(moves);
60 return moves;
61 }
62
63 };