From: Benjamin Auder Date: Wed, 25 May 2022 10:03:04 +0000 (+0200) Subject: Fix Benedict-Dark X-Git-Url: https://git.auder.net/doc/%7B%7B%20asset%28%27mixstore/current/pieces/app_dev.php?a=commitdiff_plain;h=6997e386b546c650870d64176029aff55d13edb7;p=xogo.git Fix Benedict-Dark --- diff --git a/base_rules.js b/base_rules.js index 4805f17..ded104e 100644 --- a/base_rules.js +++ b/base_rules.js @@ -748,13 +748,13 @@ export default class ChessRules { for (let x=0; x { - return (v.p == "k" || C.CannibalKings[v.p]) && v.c == color; + return C.CannibalKings[v.p] && v.c == color; })) { // Search king in appear array: const newKingIdx = m.appear.findIndex(a => { - return (a.p == "k" || C.CannibalKings[a.p]) && a.c == color; + return C.CannibalKings[a.p] && a.c == color; }); if (newKingIdx >= 0) square = [m.appear[newKingIdx].x, m.appear[newKingIdx].y]; @@ -1898,13 +1894,17 @@ export default class ChessRules { // Apply a move on board playOnBoard(move) { - for (let psq of move.vanish) this.board[psq.x][psq.y] = ""; - for (let psq of move.appear) this.board[psq.x][psq.y] = psq.c + psq.p; + for (let psq of move.vanish) + this.board[psq.x][psq.y] = ""; + for (let psq of move.appear) + this.board[psq.x][psq.y] = psq.c + psq.p; } // Un-apply the played move undoOnBoard(move) { - for (let psq of move.appear) this.board[psq.x][psq.y] = ""; - for (let psq of move.vanish) this.board[psq.x][psq.y] = psq.c + psq.p; + for (let psq of move.appear) + this.board[psq.x][psq.y] = ""; + for (let psq of move.vanish) + this.board[psq.x][psq.y] = psq.c + psq.p; } updateCastleFlags(move) { @@ -2093,7 +2093,6 @@ export default class ChessRules { return (color == "w" ? "0-1" : "1-0"); } - // NOTE: quite suboptimal for eg. Benedict (not a big deal I think) playVisual(move, r) { move.vanish.forEach(v => { // TODO: next "if" shouldn't be required diff --git a/variants/Balanced/rules.html b/variants/Balanced/rules.html index e7bb01e..6d5fa49 100644 --- a/variants/Balanced/rules.html +++ b/variants/Balanced/rules.html @@ -1,3 +1,3 @@ -

White plays first, thenn Black plays two moves, then White plays two moves, and after that the game proceeds normally.

+

White plays first, then Black plays two moves, then White plays two moves, and after that the game proceeds normally.

See the (draft) article.

diff --git a/variants/Benedict/class.js b/variants/Benedict/class.js index 7c77e8b..88609d7 100644 --- a/variants/Benedict/class.js +++ b/variants/Benedict/class.js @@ -22,10 +22,6 @@ export default class BenedictRules extends ChessRules { return false; } - canTake() { - return false; - } - // Find potential captures from a square // follow steps from x,y until something is met. findAttacks([x, y]) { @@ -39,54 +35,96 @@ export default class BenedictRules extends ChessRules { let [i, j] = [x + step[0], this.computeY(y + step[1])]; let nbSteps = 1; while (this.onBoard(i, j) && this.board[i][j] == "") { - if (a.range <= nbSteps++) continue outerLoop; + if (a.range <= nbSteps++) + continue outerLoop; i += step[0]; j = this.computeY(j + step[1]); } - if (this.onBoard(i, j) && this.getColor(i, j) == oppCol) + if ( + this.onBoard(i, j) && this.getColor(i, j) == oppCol && + (!this.options["zen"] || this.getPieceType(i, j) == "k") + ) { squares[C.CoordsToSquare({x: i, y: j})] = true; + } } } return Object.keys(squares); } postProcessPotentialMoves(moves) { - if (moves.length == 0) return moves; - const [x, y] = [moves[0].end.x, moves[0].end.y]; + if (moves.length == 0) + return moves; const color = this.getColor(moves[0].start.x, moves[0].start.y); const oppCol = C.GetOppCol(color); - moves = super.postProcessPotentialMoves(moves); + // Remove captures (NOTE: altering canTake has side effects, + // Benedict is still based on captures even if they are forbidden): + moves = super.postProcessPotentialMoves(moves) + .filter(m => this.board[m.end.x][m.end.y] == ""); moves.forEach(m => { - this.playOnBoard(m); - let attacks; + super.playOnBoard(m); + let attacks = this.findAttacks([m.end.x, m.end.y]) if (this.options["zen"]) { let endSquares = {}; - super.getZenCaptures(x, y).forEach(c => { + super.findCapturesOn([m.end.x, m.end.y], true).forEach(c => { endSquares[C.CoordsToSquare(c.end)] = true; }); - attacks = Object.keys(endSquares); + Array.prototype.push.apply(attacks, Object.keys(endSquares)); } - else attacks = this.findAttacks([m.end.x, m.end.y]) - this.undoOnBoard(m); + super.undoOnBoard(m); + m.flips = []; attacks.map(C.SquareToCoords).forEach(a => { - const p = this.getPiece(a.x, a.y); - m.appear.push(new PiPo({x: a.x, y: a.y, c: color, p: p})); - m.vanish.push(new PiPo({x: a.x, y: a.y, c: oppCol, p: p})); + m.flips.push({x: a.x, y: a.y}); }); }); return moves; } - // Moves cannot flip our king's color, so (almost) all are valid + playOnBoard(move) { + super.playOnBoard(move); + this.flipColorOf(move.flips); + } + undoOnBoard(move) { + super.undoOnBoard(move); + this.flipColorOf(move.flips); + } + + flipColorOf(flips) { + for (let xy of flips) { + const newColor = C.GetOppCol(this.getColor(xy.x, xy.y)); + this.board[xy.x][xy.y] = newColor + this.board[xy.x][xy.y][1]; + } + } + + postPlay(move) { + if (this.options["balance"] && [1, 3].includes(this.movesCount)) { + // If enemy king is flipped: game over + const oppCol = C.GetOppCol(move.vanish[0].c); + const oppKingPos = this.searchKingPos(oppCol); + if (oppKingPos[0] < 0) { + this.turn = oppCol; + this.movesCount++; + return; + } + } + super.postPlay(move); + } + + // Moves cannot flip our king's color, so all are valid filterValid(moves) { - if (this.options["balance"] && [1, 3].includes(this.movesCount)) - return moves.filter(m => m.vanish.every(v => v.p != C.KING)); return moves; } - // Since it's used just for the king, and there are no captures: + // A king under (regular) check flips color, and the game is over. underCheck(square, color) { return false; } + playVisual(move, r) { + super.playVisual(move, r); + move.flips.forEach(f => { + this.g_pieces[f.x][f.y].classList.toggle("white"); + this.g_pieces[f.x][f.y].classList.toggle("black"); + }); + } + };