From 8ca6042e7b8cffd4131e81493141ab6261300ff6 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Fri, 5 Jun 2020 21:26:32 +0200 Subject: [PATCH] Improve(?) Monochrome + simplify Zen variant --- .../src/translations/rules/Monochrome/en.pug | 5 +- .../src/translations/rules/Monochrome/es.pug | 5 +- .../src/translations/rules/Monochrome/fr.pug | 5 +- client/src/translations/variants/en.pug | 4 +- client/src/translations/variants/es.pug | 4 +- client/src/translations/variants/fr.pug | 4 +- client/src/variants/Monochrome.js | 101 ++++++++++++++++-- client/src/variants/Zen.js | 57 ++-------- 8 files changed, 120 insertions(+), 65 deletions(-) diff --git a/client/src/translations/rules/Monochrome/en.pug b/client/src/translations/rules/Monochrome/en.pug index 639f7351..81175e1b 100644 --- a/client/src/translations/rules/Monochrome/en.pug +++ b/client/src/translations/rules/Monochrome/en.pug @@ -20,7 +20,10 @@ figure.diagram-container | fen:3b4/3r4/8/8/8/8/8/3n4: figcaption Before and after Rxd7 -p Kings have no royal status. There are no en-passant captures. +p. + Kings have no royal status. There are no en-passant captures, and no castle. + "Zen" captures are possible too: if a piece A attacks a piece B + (in the usual way), then B can capture A. h3 Source diff --git a/client/src/translations/rules/Monochrome/es.pug b/client/src/translations/rules/Monochrome/es.pug index 3cb4262e..f77fc215 100644 --- a/client/src/translations/rules/Monochrome/es.pug +++ b/client/src/translations/rules/Monochrome/es.pug @@ -22,7 +22,10 @@ figure.diagram-container | fen:3b4/3r4/8/8/8/8/8/3n4: figcaption Antes y después de Rxd7 -p Los reyes no tienen estatus real. No hay capturas en-passant. +p. + Los reyes no tienen estatus real. No hay capturas en passant ni enroque. + Las capturas "Zen" también son posibles: si una pieza A ataca a un + pieza B (en el sentido habitual), entonces B puede capturar a A. h3 Fuente diff --git a/client/src/translations/rules/Monochrome/fr.pug b/client/src/translations/rules/Monochrome/fr.pug index a37e52c8..7073855e 100644 --- a/client/src/translations/rules/Monochrome/fr.pug +++ b/client/src/translations/rules/Monochrome/fr.pug @@ -22,7 +22,10 @@ figure.diagram-container | fen:3b4/3r4/8/8/8/8/8/3n4: figcaption Avant et après Rxd7 -p Les rois n'ont pas de statut royal. Il n'y pas de prises en passant. +p. + Les rois n'ont pas de statut royal. Il n'y a ni prise en passant ni roque. + Les captures "Zen" sont possible également : si une pièce A attaque une + pièce B (au sens usuel), alors B peut capturer A. h3 Source diff --git a/client/src/translations/variants/en.pug b/client/src/translations/variants/en.pug index a1e14b47..29c4a898 100644 --- a/client/src/translations/variants/en.pug +++ b/client/src/translations/variants/en.pug @@ -34,8 +34,8 @@ p. var varlist = [ "Arena", "Capture", - "Interweave", "Losers", + "Monochrome", "Suicide" ] ul @@ -162,6 +162,7 @@ p. "Baroque", "Dynamo", "Fugue", + "Interweave", "Rococo", "Maxima" ] @@ -386,7 +387,6 @@ p. "Gridolina", "Hamilton", "Magnetic", - "Monochrome", "Parachute", "Takenmake", "Wormhole" diff --git a/client/src/translations/variants/es.pug b/client/src/translations/variants/es.pug index 3cb8fa61..b6939cc7 100644 --- a/client/src/translations/variants/es.pug +++ b/client/src/translations/variants/es.pug @@ -36,8 +36,8 @@ p. var varlist = [ "Arena", "Capture", - "Interweave", "Losers", + "Monochrome", "Suicide" ] ul @@ -169,6 +169,7 @@ p. "Baroque", "Dynamo", "Fugue", + "Interweave", "Rococo", "Maxima" ] @@ -397,7 +398,6 @@ p. "Gridolina", "Hamilton", "Magnetic", - "Monochrome", "Parachute", "Takenmake", "Wormhole" diff --git a/client/src/translations/variants/fr.pug b/client/src/translations/variants/fr.pug index 5f0036bb..d108dcd1 100644 --- a/client/src/translations/variants/fr.pug +++ b/client/src/translations/variants/fr.pug @@ -35,8 +35,8 @@ p. var varlist = [ "Arena", "Capture", - "Interweave", "Losers", + "Monochrome", "Suicide" ] ul @@ -168,6 +168,7 @@ p. "Baroque", "Dynamo", "Fugue", + "Interweave", "Rococo", "Maxima" ] @@ -396,7 +397,6 @@ p. "Gridolina", "Hamilton", "Magnetic", - "Monochrome", "Parachute", "Takenmake", "Wormhole" diff --git a/client/src/variants/Monochrome.js b/client/src/variants/Monochrome.js index 31cf59ea..ba56c69a 100644 --- a/client/src/variants/Monochrome.js +++ b/client/src/variants/Monochrome.js @@ -6,6 +6,10 @@ export class MonochromeRules extends ChessRules { return false; } + static get HasFlags() { + return false; + } + static get Lines() { return [ [[4, 0], [4, 8]] ]; } @@ -43,9 +47,65 @@ export class MonochromeRules extends ChessRules { return ((x1 <= 3 && x2 >= 4) || (x1 >= 4 && x2 <= 3)); } + // follow steps from x,y until something is met. + // if met piece is opponent and same movement (asA): eat it! + findCaptures_aux([x, y], asA) { + let moves = []; + const steps = + asA != V.PAWN + ? [V.QUEEN, V.KING].includes(asA) + ? V.steps[V.ROOK].concat(V.steps[V.BISHOP]) + : V.steps[asA] + : this.turn == "w" + ? [ + [-1, -1], + [-1, 1] + ] + : [ + [1, -1], + [1, 1] + ]; + const oneStep = [V.KNIGHT, V.PAWN, V.KING].includes(asA); + outerLoop: for (let loop = 0; loop < steps.length; loop++) { + const step = steps[loop]; + let i = x + step[0]; + let j = y + step[1]; + while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { + if (oneStep) continue outerLoop; + i += step[0]; + j += step[1]; + } + if ( + V.OnBoard(i, j) && + this.getPiece(i, j) == asA && + this.canTake([i, j], [x, y]) + ) { + // eat! + moves.push(this.getBasicMove([x, y], [i, j])); + } + } + return moves; + } + + // Find possible captures from a square: look in every direction! + findCaptures(sq) { + let moves = []; + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.PAWN)); + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.ROOK)); + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.KNIGHT)); + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.BISHOP)); + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.QUEEN)); + Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.KING)); + return moves; + } + // Trim all non-capturing moves static KeepCaptures(moves) { - return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1); + return moves.filter(m => m.vanish.length == 2); + } + + getPotentialMovesFrom(sq) { + return super.getPotentialMovesFrom(sq).concat(this.findCaptures(sq)); } getAllPotentialMoves() { @@ -88,9 +148,7 @@ export class MonochromeRules extends ChessRules { for (let j = 0; j < V.size.y; j++) { if ( this.board[i][j] != V.EMPTY && - this.getPotentialMovesFrom([i, j]).some(m => - // Warning: discard castle moves - m.vanish.length == 2 && m.appear.length == 1) + this.getPotentialMovesFrom([i, j]).some(m => m.vanish.length == 2) ) { return true; } @@ -120,7 +178,7 @@ export class MonochromeRules extends ChessRules { } getCurrentScore() { - // Is there anything in my half board? + // Is there anything in opponent's half board? const color = V.GetOppCol(this.turn); const xBounds = color == 'w' ? [4,7] : [0,3]; let nothingHere = true; @@ -138,8 +196,8 @@ export class MonochromeRules extends ChessRules { } static GenRandInitFen(randomness) { - // Remove the en-passant part of the FEN - const fen = ChessRules.GenRandInitFen(randomness).slice(0, -2); + // Remove the en-passant + castle part of the FEN + const fen = ChessRules.GenRandInitFen(randomness).slice(0, -6); const firstSpace = fen.indexOf(' '); return ( fen.substr(0, firstSpace).replace(/[A-Z]/g, (c) => c.toLowerCase()) + @@ -164,4 +222,33 @@ export class MonochromeRules extends ChessRules { } return evaluation; } + + getNotation(move) { + // Translate initial square (because pieces may fly unusually!) + const initialSquare = V.CoordsToSquare(move.start); + + // Translate final square + const finalSquare = V.CoordsToSquare(move.end); + + let notation = ""; + const piece = this.getPiece(move.start.x, move.start.y); + if (piece == V.PAWN) { + // pawn move (TODO: enPassant indication) + if (move.vanish.length == 2) { + // capture + notation = initialSquare + "x" + finalSquare; + } + else notation = finalSquare; + if (piece != move.appear[0].p) + //promotion + notation += "=" + move.appear[0].p.toUpperCase(); + } + else { + // Piece movement + notation = piece.toUpperCase(); + if (move.vanish.length > 1) notation += initialSquare + "x"; + notation += finalSquare; + } + return notation; + } }; diff --git a/client/src/variants/Zen.js b/client/src/variants/Zen.js index 0424e07f..808d5436 100644 --- a/client/src/variants/Zen.js +++ b/client/src/variants/Zen.js @@ -66,6 +66,7 @@ export class ZenRules extends ChessRules { const oneStep = [V.KNIGHT,V.PAWN].includes(asA); //we don't capture king const lastRank = color == "w" ? 0 : V.size.x - 1; const promotionPieces = [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]; + const oppCol = V.GetOppCol(color); outerLoop: for (let loop = 0; loop < steps.length; loop++) { const step = steps[loop]; let i = x + step[0]; @@ -77,7 +78,7 @@ export class ZenRules extends ChessRules { } if ( V.OnBoard(i, j) && - this.getColor(i, j) == V.GetOppCol(color) && + this.getColor(i, j) == oppCol && this.getPiece(i, j) == asA ) { // eat! @@ -98,13 +99,11 @@ export class ZenRules extends ChessRules { // Find possible captures from a square: look in every direction! findCaptures(sq) { let moves = []; - Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.PAWN)); Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.ROOK)); Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.KNIGHT)); Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.BISHOP)); Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.QUEEN)); - return moves; } @@ -112,49 +111,8 @@ export class ZenRules extends ChessRules { return false; //captures handled separately } - getPotentialPawnMoves([x, y]) { - let moves = super.getPotentialPawnMoves([x, y]); - // Add "zen" captures - Array.prototype.push.apply(moves, this.findCaptures([x, y])); - return moves; - } - - getPotentialRookMoves(sq) { - let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.ROOK]); - let captures = this.findCaptures(sq); - return noCaptures.concat(captures); - } - - getPotentialKnightMoves(sq) { - let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep"); - let captures = this.findCaptures(sq); - return noCaptures.concat(captures); - } - - getPotentialBishopMoves(sq) { - let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]); - let captures = this.findCaptures(sq); - return noCaptures.concat(captures); - } - - getPotentialQueenMoves(sq) { - let noCaptures = this.getSlideNJumpMoves( - sq, - V.steps[V.ROOK].concat(V.steps[V.BISHOP]) - ); - let captures = this.findCaptures(sq); - return noCaptures.concat(captures); - } - - getPotentialKingMoves(sq) { - // Initialize with normal moves - let noCaptures = this.getSlideNJumpMoves( - sq, - V.steps[V.ROOK].concat(V.steps[V.BISHOP]), - "oneStep" - ); - let captures = this.findCaptures(sq); - return noCaptures.concat(captures).concat(this.getCastleMoves(sq)); + getPotentialMovesFrom(sq) { + return super.getPotentialMovesFrom(sq).concat(this.findCaptures(sq)); } getNotation(move) { @@ -175,15 +133,16 @@ export class ZenRules extends ChessRules { const piece = this.getPiece(move.start.x, move.start.y); if (piece == V.PAWN) { // pawn move (TODO: enPassant indication) - if (move.vanish.length > 1) { + if (move.vanish.length == 2) { // capture notation = initialSquare + "x" + finalSquare; - } //no capture + } else notation = finalSquare; if (piece != move.appear[0].p) //promotion notation += "=" + move.appear[0].p.toUpperCase(); - } else { + } + else { // Piece movement notation = piece.toUpperCase(); if (move.vanish.length > 1) notation += initialSquare + "x"; -- 2.44.0