Add Colorbound Clobberers (R. Betza)
[vchess.git] / client / src / variants / Losers.js
CommitLineData
0c3fe8a6
BA
1import { ChessRules } from "@/base_rules";
2import { ArrayFun } from "@/utils/array";
3import { randInt } from "@/utils/alea";
4
32f6285e 5export class LosersRules extends ChessRules {
6b7b2cf7
BA
6 // Trim all non-capturing moves
7 static KeepCaptures(moves) {
57d9b2c4 8 return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1);
dac39588
BA
9 }
10
801e2870 11 // Stop at the first capture found (if any)
6808d7a1 12 atLeastOneCapture() {
dac39588
BA
13 const color = this.turn;
14 const oppCol = V.GetOppCol(color);
6808d7a1
BA
15 for (let i = 0; i < V.size.x; i++) {
16 for (let j = 0; j < V.size.y; j++) {
6b7b2cf7
BA
17 if (
18 this.board[i][j] != V.EMPTY &&
19 this.getColor(i, j) != oppCol &&
20 this.getPotentialMovesFrom([i, j]).some(m =>
57d9b2c4 21 // Warning: discard castle moves
6b7b2cf7
BA
22 m.vanish.length == 2 && m.appear.length == 1)
23 ) {
24 return true;
dac39588
BA
25 }
26 }
27 }
28 return false;
29 }
30
6808d7a1
BA
31 getPossibleMovesFrom(sq) {
32 let moves = this.filterValid(this.getPotentialMovesFrom(sq));
6b7b2cf7
BA
33 const captureMoves = V.KeepCaptures(moves);
34 if (captureMoves.length > 0) return captureMoves;
35 if (this.atLeastOneCapture()) return [];
dac39588
BA
36 return moves;
37 }
38
6808d7a1 39 getAllValidMoves() {
6b7b2cf7 40 const moves = super.getAllValidMoves();
a34caace
BA
41 if (moves.some(m => m.vanish.length == 2 && m.appear.length == 1))
42 return V.KeepCaptures(moves);
dac39588
BA
43 return moves;
44 }
45
6808d7a1 46 getCurrentScore() {
6b7b2cf7
BA
47 // If only my king remains, I win
48 const color = this.turn;
49 let onlyKing = true;
50 outerLoop: for (let i=0; i<V.size.x; i++) {
51 for (let j=0; j<V.size.y; j++) {
52 if (
53 this.board[i][j] != V.EMPTY &&
54 this.getColor(i,j) == color &&
55 this.getPiece(i,j) != V.KING
56 ) {
57 onlyKing = false;
58 break outerLoop;
59 }
60 }
61 }
62 if (onlyKing) return color == "w" ? "1-0" : "0-1";
63 if (this.atLeastOneMove()) return "*";
64 // No valid move: the side who cannot move (or is checkmated) wins
6808d7a1 65 return this.turn == "w" ? "1-0" : "0-1";
dac39588
BA
66 }
67
6808d7a1 68 evalPosition() {
6b7b2cf7
BA
69 // Less material is better (more subtle in fact but...)
70 return -super.evalPosition();
dac39588 71 }
6808d7a1 72};