Fix king tracking in Fusion variant
[vchess.git] / client / src / variants / Kingsmaker.js
CommitLineData
0f7762c1
BA
1import { ChessRules } from "@/base_rules";
2
3export class KingsmakerRules extends ChessRules {
4
5 static IsGoodPosition(position) {
6 if (position.length == 0) return false;
7 const rows = position.split("/");
8 if (rows.length != V.size.x) return false;
9 let kings = { "k": 0, "K": 0 };
10 for (let row of rows) {
11 let sumElts = 0;
12 for (let i = 0; i < row.length; i++) {
13 if (['K','k'].includes(row[i])) kings[row[i]]++;
14 if (V.PIECES.includes(row[i].toLowerCase())) sumElts++;
15 else {
16 const num = parseInt(row[i], 10);
17 if (isNaN(num) || num <= 0) return false;
18 sumElts += num;
19 }
20 }
21 if (sumElts != V.size.y) return false;
22 }
23 // At least one king per color.
24 if (Object.values(kings).some(v => v == 0)) return false;
25 return true;
26 }
27
28 scanKings() {}
29
30 getPotentialMovesFrom([x, y]) {
31 const moves = super.getPotentialMovesFrom([x, y]);
32 if (this.getPiece(x, y) != V.PAWN) return moves;
33 const c = this.getColor(x, y);
34 const oppCol = V.GetOppCol(c);
35 const forward = (c == 'w' ? -1 : 1);
36 const lastRanks = (c == 'w' ? [0, 1] : [7, 6]);
37 let newKingMoves = [];
38 if (lastRanks.includes(x + forward)) {
39 // Manually add promotion into enemy king:
40 const trials = [
41 { step: [forward, 0] },
42 { step: [forward, 1], capture: true },
43 { step: [forward, -1], capture: true }
44 ];
45 for (let s of trials) {
46 const [i, j] = [x + s.step[0], y + s.step[1]];
47 if (
48 V.OnBoard(i, j) &&
49 (
50 (!s.capture && this.board[i][j] == V.EMPTY) ||
51 (
52 s.capture &&
53 this.board[i][j] != V.EMPTY &&
54 this.getColor(i, j) == oppCol
55 )
56 )
57 ) {
58 newKingMoves.push(
59 super.getBasicMove([x, y], [i, j], { c: oppCol, p: V.KING })
60 );
61 }
62 }
63 }
64 return moves.concat(newKingMoves);
65 }
66
67 underCheck(color) {
68 // First at first check found (if any)
69 const oppCol = V.GetOppCol(color);
70 for (let i=0; i<8; i++) {
71 for (let j=0; j<8; j++) {
72 if (
73 this.board[i][j] != V.EMPTY &&
74 this.getPiece(i, j) == V.KING &&
75 this.getColor(i, j) == color
76 ) {
77 if (super.isAttacked([i, j], oppCol)) return true;
78 }
79 }
80 }
81 return false;
82 }
83
84 getCheckSquares() {
85 const color = this.turn;
86 const oppCol = V.GetOppCol(color);
87 let res = [];
88 // Scan all kings
89 for (let i=0; i<8; i++) {
90 for (let j=0; j<8; j++) {
91 if (
92 this.board[i][j] != V.EMPTY &&
93 this.getPiece(i, j) == V.KING &&
94 this.getColor(i, j) == color
95 ) {
96 if (super.isAttacked([i, j], oppCol)) res.push([i, j]);
97 }
98 }
99 }
100 return res;
101 }
102
103 postPlay(move) {
104 this.updateCastleFlags(move, move.vanish[0].p);
105 }
106
107 postUndo() {}
108
109 static get VALUES() {
110 // Assign -5 to the king, so that the bot sometimes promote into king
111 return Object.assign({}, ChessRules.VALUES, { k: -5 });
112 }
113
114};