Fix Benedict-Dark
[xogo.git] / variants / Benedict / class.js
CommitLineData
41534b92
BA
1import ChessRules from "/base_rules.js";
2import PiPo from "/utils/PiPo.js";
3
4export default class BenedictRules extends ChessRules {
5
6 static get Options() {
7 return {
cc2c7183 8 select: C.Options.select,
41534b92 9 check: [],
b99ce1fb
BA
10 styles: [
11 "balance",
12 "cylinder",
13 "dark",
14 "doublemove",
15 "progressive",
16 "zen"
17 ]
41534b92
BA
18 };
19 }
20
21 get hasEnpassant() {
22 return false;
23 }
24
41534b92
BA
25 // Find potential captures from a square
26 // follow steps from x,y until something is met.
27 findAttacks([x, y]) {
28 const [color, piece] = [this.getColor(x, y), this.getPiece(x, y)];
cc2c7183 29 const oppCol = C.GetOppCol(color);
41534b92 30 let squares = {};
c9ab0340
BA
31 const specs = this.pieces(color, x, y)[piece];
32 const attacks = specs.attack || specs.moves;
33 for (let a of attacks) {
34 outerLoop: for (let step of a.steps) {
35 let [i, j] = [x + step[0], this.computeY(y + step[1])];
36 let nbSteps = 1;
37 while (this.onBoard(i, j) && this.board[i][j] == "") {
6997e386
BA
38 if (a.range <= nbSteps++)
39 continue outerLoop;
c9ab0340
BA
40 i += step[0];
41 j = this.computeY(j + step[1]);
42 }
6997e386
BA
43 if (
44 this.onBoard(i, j) && this.getColor(i, j) == oppCol &&
45 (!this.options["zen"] || this.getPieceType(i, j) == "k")
46 ) {
c9ab0340 47 squares[C.CoordsToSquare({x: i, y: j})] = true;
6997e386 48 }
41534b92 49 }
41534b92
BA
50 }
51 return Object.keys(squares);
52 }
53
54 postProcessPotentialMoves(moves) {
6997e386
BA
55 if (moves.length == 0)
56 return moves;
41534b92 57 const color = this.getColor(moves[0].start.x, moves[0].start.y);
cc2c7183 58 const oppCol = C.GetOppCol(color);
6997e386
BA
59 // Remove captures (NOTE: altering canTake has side effects,
60 // Benedict is still based on captures even if they are forbidden):
61 moves = super.postProcessPotentialMoves(moves)
62 .filter(m => this.board[m.end.x][m.end.y] == "");
41534b92 63 moves.forEach(m => {
6997e386
BA
64 super.playOnBoard(m);
65 let attacks = this.findAttacks([m.end.x, m.end.y])
41534b92
BA
66 if (this.options["zen"]) {
67 let endSquares = {};
6997e386 68 super.findCapturesOn([m.end.x, m.end.y], true).forEach(c => {
cc2c7183 69 endSquares[C.CoordsToSquare(c.end)] = true;
41534b92 70 });
6997e386 71 Array.prototype.push.apply(attacks, Object.keys(endSquares));
41534b92 72 }
6997e386
BA
73 super.undoOnBoard(m);
74 m.flips = [];
cc2c7183 75 attacks.map(C.SquareToCoords).forEach(a => {
6997e386 76 m.flips.push({x: a.x, y: a.y});
41534b92
BA
77 });
78 });
79 return moves;
80 }
81
6997e386
BA
82 playOnBoard(move) {
83 super.playOnBoard(move);
84 this.flipColorOf(move.flips);
85 }
86 undoOnBoard(move) {
87 super.undoOnBoard(move);
88 this.flipColorOf(move.flips);
89 }
90
91 flipColorOf(flips) {
92 for (let xy of flips) {
93 const newColor = C.GetOppCol(this.getColor(xy.x, xy.y));
94 this.board[xy.x][xy.y] = newColor + this.board[xy.x][xy.y][1];
95 }
96 }
97
98 postPlay(move) {
99 if (this.options["balance"] && [1, 3].includes(this.movesCount)) {
100 // If enemy king is flipped: game over
101 const oppCol = C.GetOppCol(move.vanish[0].c);
102 const oppKingPos = this.searchKingPos(oppCol);
103 if (oppKingPos[0] < 0) {
104 this.turn = oppCol;
105 this.movesCount++;
106 return;
107 }
108 }
109 super.postPlay(move);
110 }
111
112 // Moves cannot flip our king's color, so all are valid
41534b92 113 filterValid(moves) {
41534b92
BA
114 return moves;
115 }
116
6997e386 117 // A king under (regular) check flips color, and the game is over.
41534b92
BA
118 underCheck(square, color) {
119 return false;
120 }
121
6997e386
BA
122 playVisual(move, r) {
123 super.playVisual(move, r);
124 move.flips.forEach(f => {
125 this.g_pieces[f.x][f.y].classList.toggle("white");
126 this.g_pieces[f.x][f.y].classList.toggle("black");
127 });
128 }
129
41534b92 130};