From 278a28a16bfee8c64746e2ec1423259009bff886 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Thu, 25 Mar 2021 12:18:43 +0100 Subject: [PATCH] Pandemonium 1 & 2, Stealthbomb 1 & 2 --- client/src/translations/en.js | 6 +- client/src/translations/es.js | 6 +- client/src/translations/fr.js | 6 +- .../{Pandemonium => Pandemonium1}/en.pug | 0 .../{Pandemonium => Pandemonium1}/es.pug | 0 .../{Pandemonium => Pandemonium1}/fr.pug | 0 .../translations/rules/Pandemonium2/en.pug | 14 ++ .../translations/rules/Pandemonium2/es.pug | 14 ++ .../translations/rules/Pandemonium2/fr.pug | 14 ++ .../{Stealthbomb => Stealthbomb1}/en.pug | 2 + .../{Stealthbomb => Stealthbomb1}/es.pug | 2 + .../{Stealthbomb => Stealthbomb1}/fr.pug | 2 + .../translations/rules/Stealthbomb2/en.pug | 7 + .../translations/rules/Stealthbomb2/es.pug | 7 + .../translations/rules/Stealthbomb2/fr.pug | 7 + .../src/translations/rules/Wildebeest/en.pug | 5 +- .../src/translations/rules/Wildebeest/es.pug | 5 +- .../src/translations/rules/Wildebeest/fr.pug | 3 +- client/src/translations/variants/en.pug | 6 +- client/src/translations/variants/es.pug | 6 +- client/src/translations/variants/fr.pug | 6 +- client/src/variants/Pandemonium1.js | 128 +++++++++++++ .../{Pandemonium.js => Pandemonium2.js} | 178 +++--------------- .../{Stealthbomb.js => Stealthbomb1.js} | 7 +- client/src/variants/Stealthbomb2.js | 27 +++ client/src/variants/Wildebeest.js | 10 +- server/db/populate.sql | 6 +- 27 files changed, 299 insertions(+), 175 deletions(-) rename client/src/translations/rules/{Pandemonium => Pandemonium1}/en.pug (100%) rename client/src/translations/rules/{Pandemonium => Pandemonium1}/es.pug (100%) rename client/src/translations/rules/{Pandemonium => Pandemonium1}/fr.pug (100%) create mode 100644 client/src/translations/rules/Pandemonium2/en.pug create mode 100644 client/src/translations/rules/Pandemonium2/es.pug create mode 100644 client/src/translations/rules/Pandemonium2/fr.pug rename client/src/translations/rules/{Stealthbomb => Stealthbomb1}/en.pug (96%) rename client/src/translations/rules/{Stealthbomb => Stealthbomb1}/es.pug (96%) rename client/src/translations/rules/{Stealthbomb => Stealthbomb1}/fr.pug (96%) create mode 100644 client/src/translations/rules/Stealthbomb2/en.pug create mode 100644 client/src/translations/rules/Stealthbomb2/es.pug create mode 100644 client/src/translations/rules/Stealthbomb2/fr.pug create mode 100644 client/src/variants/Pandemonium1.js rename client/src/variants/{Pandemonium.js => Pandemonium2.js} (78%) rename client/src/variants/{Stealthbomb.js => Stealthbomb1.js} (97%) create mode 100644 client/src/variants/Stealthbomb2.js diff --git a/client/src/translations/en.js b/client/src/translations/en.js index a86b6e1d..38155cf2 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -181,7 +181,8 @@ export const translations = { "Augmented Queens": "Augmented Queens", "Balanced sliders & leapers": "Balanced sliders & leapers", "Baroque Music": "Baroque Music", - "Beware the bomb": "Beware the bomb", + "Beware the bomb (v1)": "Beware the bomb (v1)", + "Beware the bomb (v2)": "Beware the bomb (v2)", "Big board": "Big board", "Bishop versus pawns": "Bishop versus pawns", "Board upside down": "Board upside down", @@ -277,7 +278,8 @@ export const translations = { "New fairy pieces": "New fairy pieces", "No paralyzed pieces": "No paralyzed pieces", "No-check mode": "No-check mode", - "Noise and confusion": "Noise and confusion", + "Noise and confusion (v1)": "Noise and confusion (v1)", + "Noise and confusion (v2)": "Noise and confusion (v2)", "Non-conformism and utopia": "Non-conformism and utopia", "Occupy the enemy palace": "Occupy the enemy palace", "Paralyzed pieces": "Paralyzed pieces", diff --git a/client/src/translations/es.js b/client/src/translations/es.js index a5cd67b5..9e8088b9 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -181,7 +181,8 @@ export const translations = { "Augmented Queens": "Damas aumentadas", "Balanced sliders & leapers": "Modos de desplazamiento equilibrados", "Baroque Music": "Música Barroca", - "Beware the bomb": "Cuidado con la bomba", + "Beware the bomb (v1)": "Cuidado con la bomba (v1)", + "Beware the bomb (v2)": "Cuidado con la bomba (v2)", "Big board": "Gran tablero", "Bishop versus pawns": "Alfil contra peones", "Board upside down": "Tablero al revés", @@ -277,7 +278,8 @@ export const translations = { "New fairy pieces": "Nuevas piezas magicas", "No paralyzed pieces": "No piezas paralizadas", "No-check mode": "Modo sin jaque", - "Noise and confusion": "Ruido y confusión", + "Noise and confusion (v1)": "Ruido y confusión (v1)", + "Noise and confusion (v2)": "Ruido y confusión (v2)", "Non-conformism and utopia": "No-conformismo y utopía", "Occupy the enemy palace": "Ocupar el palacio enemigo", "Paralyzed pieces": "Piezas paralizadas", diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index 9ca47171..c095bb0b 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -181,7 +181,8 @@ export const translations = { "Augmented Queens": "Dames augmentées", "Balanced sliders & leapers": "Modes de déplacement équilibrés", "Baroque Music": "Musique Baroque", - "Beware the bomb": "Attention à la bombe", + "Beware the bomb (v1)": "Attention à la bombe (v1)", + "Beware the bomb (v2)": "Attention à la bombe (v2)", "Big board": "Grand échiquier", "Bishop versus pawns": "Fou contre pions", "Board upside down": "Échiquier à l'envers", @@ -277,7 +278,8 @@ export const translations = { "New fairy pieces": "Nouvelles pièces féériques", "No paralyzed pieces": "Pas de pièces paralysées", "No-check mode": "Mode sans échec", - "Noise and confusion": "Bruit et confusion", + "Noise and confusion (v1)": "Bruit et confusion (v1)", + "Noise and confusion (v2)": "Bruit et confusion (v2)", "Non-conformism and utopia": "Non-conformisme et utopie", "Occupy the enemy palace": "Occuper le palais ennemi", "Paralyzed pieces": "Pièces paralysées", diff --git a/client/src/translations/rules/Pandemonium/en.pug b/client/src/translations/rules/Pandemonium1/en.pug similarity index 100% rename from client/src/translations/rules/Pandemonium/en.pug rename to client/src/translations/rules/Pandemonium1/en.pug diff --git a/client/src/translations/rules/Pandemonium/es.pug b/client/src/translations/rules/Pandemonium1/es.pug similarity index 100% rename from client/src/translations/rules/Pandemonium/es.pug rename to client/src/translations/rules/Pandemonium1/es.pug diff --git a/client/src/translations/rules/Pandemonium/fr.pug b/client/src/translations/rules/Pandemonium1/fr.pug similarity index 100% rename from client/src/translations/rules/Pandemonium/fr.pug rename to client/src/translations/rules/Pandemonium1/fr.pug diff --git a/client/src/translations/rules/Pandemonium2/en.pug b/client/src/translations/rules/Pandemonium2/en.pug new file mode 100644 index 00000000..8f1570f3 --- /dev/null +++ b/client/src/translations/rules/Pandemonium2/en.pug @@ -0,0 +1,14 @@ +p.boxed + | All pieces can promote. Captured units can be dropped later. + | 10x8 board. Some new pieces. + +figure.diagram-container + .diagram + | fen:rnbqkmcbnr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNBQKMCBNR: + figcaption Initial deterministic position. + +p + a(href="/#/variants/Pandemonium1") Pandemonium1 + |  on a 10x8 board. + | Pawns move as in orthodox chess, and promotions + | occur only on the final rank. diff --git a/client/src/translations/rules/Pandemonium2/es.pug b/client/src/translations/rules/Pandemonium2/es.pug new file mode 100644 index 00000000..863d3e4a --- /dev/null +++ b/client/src/translations/rules/Pandemonium2/es.pug @@ -0,0 +1,14 @@ +p.boxed + | Todas las piezas pueden promocionarse. Las unidades capturadas son + | en paracaídas más tarde. Tablero de ajedrez 10x8. Algunas piezas nuevas. + +figure.diagram-container + .diagram + | fen:rnbqkmcbnr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNBQKMCBNR: + figcaption Posición inicial determinista. + +p + a(href="/#/variants/Pandemonium1") Pandemonium1 + |  en un tablero 10x8. + | Los peones se mueven como en el ajedrez ortodoxo, + | y las promociones solo ocurren en la última fila. diff --git a/client/src/translations/rules/Pandemonium2/fr.pug b/client/src/translations/rules/Pandemonium2/fr.pug new file mode 100644 index 00000000..c70bd965 --- /dev/null +++ b/client/src/translations/rules/Pandemonium2/fr.pug @@ -0,0 +1,14 @@ +p.boxed + | Toutes les pièces peuvent être promues. Les unités capturées sont + | parachutées plus tard. Échiquier 10x8. Quelques nouvelles pièces. + +figure.diagram-container + .diagram + | fen:rnbqkmcbnr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNBQKMCBNR: + figcaption Position initiale déterministe. + +p + a(href="/#/variants/Pandemonium1") Pandemonium1 + |  sur un échiquier 10x8. + | Les pions se déplacent comme aux échecs orthodoxes, + | et les promotions ne surviennent que sur la dernière rangée. diff --git a/client/src/translations/rules/Stealthbomb/en.pug b/client/src/translations/rules/Stealthbomb1/en.pug similarity index 96% rename from client/src/translations/rules/Stealthbomb/en.pug rename to client/src/translations/rules/Stealthbomb1/en.pug index 09ba3bdd..6b1b9800 100644 --- a/client/src/translations/rules/Stealthbomb/en.pug +++ b/client/src/translations/rules/Stealthbomb1/en.pug @@ -29,3 +29,5 @@ p | . This variant is Stealthbomber on a(href="fishrandom.io") fishrandom.io | , and "Stealthbomb" here... why not :-) + +p Inventor: Jim Winslow (1992) diff --git a/client/src/translations/rules/Stealthbomb/es.pug b/client/src/translations/rules/Stealthbomb1/es.pug similarity index 96% rename from client/src/translations/rules/Stealthbomb/es.pug rename to client/src/translations/rules/Stealthbomb1/es.pug index 758e7e9a..9c0ae6a9 100644 --- a/client/src/translations/rules/Stealthbomb/es.pug +++ b/client/src/translations/rules/Stealthbomb1/es.pug @@ -29,3 +29,5 @@ p | . Esta variante es Stealthbomber en a(href="fishrandom.io") fishrandom.io | , y "Stealthbomb" aquí... ¿Por qué no? :-) + +p Inventor: Jim Winslow (1992) diff --git a/client/src/translations/rules/Stealthbomb/fr.pug b/client/src/translations/rules/Stealthbomb1/fr.pug similarity index 96% rename from client/src/translations/rules/Stealthbomb/fr.pug rename to client/src/translations/rules/Stealthbomb1/fr.pug index ecf61cc1..3510e483 100644 --- a/client/src/translations/rules/Stealthbomb/fr.pug +++ b/client/src/translations/rules/Stealthbomb1/fr.pug @@ -29,3 +29,5 @@ p | . Cette variante est Stealthbomber sur a(href="fishrandom.io") fishrandom.io | , et "Stealthbomb" ici... pourquoi pas :-) + +p Inventeur : Jim Winslow (1992) diff --git a/client/src/translations/rules/Stealthbomb2/en.pug b/client/src/translations/rules/Stealthbomb2/en.pug new file mode 100644 index 00000000..6ee7beb4 --- /dev/null +++ b/client/src/translations/rules/Stealthbomb2/en.pug @@ -0,0 +1,7 @@ +p.boxed. + One pawn of each side hides a bomb, + which can be triggered instead of playing a move. + +p + a(href="/#/variants/Stealthbomb1") Stealthbomb1 + | , where only pawns can hold a bomb. diff --git a/client/src/translations/rules/Stealthbomb2/es.pug b/client/src/translations/rules/Stealthbomb2/es.pug new file mode 100644 index 00000000..b41a979f --- /dev/null +++ b/client/src/translations/rules/Stealthbomb2/es.pug @@ -0,0 +1,7 @@ +p.boxed. + Un peon de cada campamento esconde una bomba, + que se puede activar en lugar de ejecutar un movimiento. + +p + a(href="/#/variants/Stealthbomb1") Stealthbomb1 + | , donde solo los peones pueden llevar una bomba. diff --git a/client/src/translations/rules/Stealthbomb2/fr.pug b/client/src/translations/rules/Stealthbomb2/fr.pug new file mode 100644 index 00000000..14a90b8f --- /dev/null +++ b/client/src/translations/rules/Stealthbomb2/fr.pug @@ -0,0 +1,7 @@ +p.boxed. + Un pion de chaque camp cache une bombe, + qui peut être déclenchée au lieu de jouer un coup. + +p + a(href="/#/variants/Stealthbomb1") Stealthbomb1 + | , où seuls les pions peuvent porter une bombe. diff --git a/client/src/translations/rules/Wildebeest/en.pug b/client/src/translations/rules/Wildebeest/en.pug index 5f0b6311..16323ee6 100644 --- a/client/src/translations/rules/Wildebeest/en.pug +++ b/client/src/translations/rules/Wildebeest/en.pug @@ -24,8 +24,9 @@ p. which will end next to him on the other side. p. - When a pawn reaches last rank, it can promote - into a queen or a wildebeest (only). + When a pawn reaches the last rank, it promotes into a queen or a + wildebeest (only). Promotion is also possible (optionally) on 9th rank. + This is an experimental addition to the official rules. h3 Source diff --git a/client/src/translations/rules/Wildebeest/es.pug b/client/src/translations/rules/Wildebeest/es.pug index a407e332..e5e6d7dd 100644 --- a/client/src/translations/rules/Wildebeest/es.pug +++ b/client/src/translations/rules/Wildebeest/es.pug @@ -24,7 +24,10 @@ p. el rey puede saltar cualquier número de casillas (libres) a la torre, que terminará junto a él en el otro lado. -p Un peón en la última fila es promovido a dama o ñu solamente. +p. + Un peón que llega a la última fila es promovido a dama o ñu solamente. + La promoción también es posible (opcionalmente) en la novena fila. + Es una adición experimental a las reglas oficiales. h3 Fuente diff --git a/client/src/translations/rules/Wildebeest/fr.pug b/client/src/translations/rules/Wildebeest/fr.pug index fb04759a..52dfc3d6 100644 --- a/client/src/translations/rules/Wildebeest/fr.pug +++ b/client/src/translations/rules/Wildebeest/fr.pug @@ -26,7 +26,8 @@ p. p. Un pion arrivé sur la dernière rangée se promeut en une dame ou un gnou - seulement. + seulement. La promotion est également possible (optionnellement) + sur la 9eme rangée. C'est un ajout expérimental aux règles officielles. h3 Source diff --git a/client/src/translations/variants/en.pug b/client/src/translations/variants/en.pug index c933d9c7..0da01791 100644 --- a/client/src/translations/variants/en.pug +++ b/client/src/translations/variants/en.pug @@ -222,7 +222,8 @@ p. "Dark", "Hidden", "Hiddenqueen", - "Stealthbomb", + "Stealthbomb1", + "Stealthbomb2", "Synchrone1", "Synchrone2" ] @@ -480,7 +481,8 @@ p. "Iceage", "Kingsmaker", "Magnetic", - "Pandemonium", + "Pandemonium1", + "Pandemonium2", "Refusal1", "Refusal2", "Relayup", diff --git a/client/src/translations/variants/es.pug b/client/src/translations/variants/es.pug index 81fad93f..cc246bd5 100644 --- a/client/src/translations/variants/es.pug +++ b/client/src/translations/variants/es.pug @@ -229,7 +229,8 @@ p. "Dark", "Hidden", "Hiddenqueen", - "Stealthbomb", + "Stealthbomb1", + "Stealthbomb2", "Synchrone1", "Synchrone2" ] @@ -490,7 +491,8 @@ p. "Iceage", "Kingsmaker", "Magnetic", - "Pandemonium", + "Pandemonium1", + "Pandemonium2", "Refusal1", "Refusal2", "Relayup", diff --git a/client/src/translations/variants/fr.pug b/client/src/translations/variants/fr.pug index 6743ce25..ae68c665 100644 --- a/client/src/translations/variants/fr.pug +++ b/client/src/translations/variants/fr.pug @@ -228,7 +228,8 @@ p. "Dark", "Hidden", "Hiddenqueen", - "Stealthbomb", + "Stealthbomb1", + "Stealthbomb2", "Synchrone1", "Synchrone2" ] @@ -488,7 +489,8 @@ p. "Iceage", "Kingsmaker", "Magnetic", - "Pandemonium", + "Pandemonium1", + "Pandemonium2", "Refusal1", "Refusal2", "Relayup", diff --git a/client/src/variants/Pandemonium1.js b/client/src/variants/Pandemonium1.js new file mode 100644 index 00000000..579ee9ce --- /dev/null +++ b/client/src/variants/Pandemonium1.js @@ -0,0 +1,128 @@ +import { Pandemonium2Rules } from "@/variants/Pandemonium2"; + +export class Pandemonium1Rules extends Pandemonium2Rules { + + static get PawnSpecs() { + return Object.assign( + { }, + Pandemonium2Rules.PawnSpecs, + { threeSquares: true } + ); + } + + static get size() { + return { x: 10, y: 10}; + } + + static IsGoodEnpassant(enpassant) { + if (enpassant != "-") { + const squares = enpassant.split(","); + if (squares.length > 2) return false; + for (let sq of squares) { + if (!sq.match(/[a-j0-9]/)) return false; + } + } + return true; + } + + static GenRandInitFen(randomness) { + const baseFen = Pandemonium2Rules.GenRandInitFen(randomness) + return baseFen.substr(0, 22) + "91/91/" + baseFen.substr(22); + } + + getEnpassantFen() { + const L = this.epSquares.length; + if (!this.epSquares[L - 1]) return "-"; //no en-passant + let res = ""; + this.epSquares[L - 1].forEach(sq => { + res += V.CoordsToSquare(sq) + ","; + }); + return res.slice(0, -1); //remove last comma + } + + getEpSquare(moveOrSquare) { + if (!moveOrSquare) return undefined; + if (typeof moveOrSquare === "string") { + const square = moveOrSquare; + if (square == "-") return undefined; + let res = []; + square.split(",").forEach(sq => { + res.push(V.SquareToCoords(sq)); + }); + return res; + } + // Argument is a move: + const move = moveOrSquare; + const [sx, sy, ex] = [move.start.x, move.start.y, move.end.x]; + if (this.getPiece(sx, sy) == V.PAWN && Math.abs(sx - ex) >= 2) { + const step = (ex - sx) / Math.abs(ex - sx); + let res = [{ + x: sx + step, + y: sy + }]; + if (sx + 2 * step != ex) { + // 3-squares jump + res.push({ + x: sx + 2 * step, + y: sy + }); + } + return res; + } + return undefined; //default + } + + applyPromotions(moves, promoted) { + const lastRanks = (this.turn == 'w' ? [0, 1] : [V.size.x - 1, V.size.x]); + let promotions = []; + moves.forEach(m => { + if (lastRanks.includes(m.start.x) || lastRanks.includes(m.end.x)) { + let pMove = JSON.parse(JSON.stringify(m)); + pMove.appear[0].p = promoted; + promotions.push(pMove); + } + }); + Array.prototype.push.apply(moves, promotions); + } + + addPawnMoves([x1, y1], [x2, y2], moves) { + const color = this.turn; + const lastRanks = (color == "w" ? [0, 1] : [V.size.x - 1, V.size.x - 2]); + if (!lastRanks.includes(x2)) { + moves.push(this.getBasicMove([x1, y1], [x2, y2])); + return; + } + let finalPieces = [V.GILDING]; + if (x2 == lastRanks[1]) finalPieces.push(V.PAWN); + for (let piece of finalPieces) { + const tr = (piece != V.PAWN ? { c: color, p: piece } : null); + moves.push(this.getBasicMove([x1, y1], [x2, y2], tr)); + } + } + + getEnpassantCaptures([x, y], shiftX) { + const Lep = this.epSquares.length; + const epSquare = this.epSquares[Lep - 1]; + let moves = []; + if (!!epSquare) { + for (let epsq of epSquare) { + // TODO: some redundant checks + if (epsq.x == x + shiftX && Math.abs(epsq.y - y) == 1) { + let enpassantMove = this.getBasicMove([x, y], [epsq.x, epsq.y]); + // WARNING: the captured pawn may be diagonally behind us, + // if it's a 3-squares jump and we take on 1st passing square + const px = this.board[x][epsq.y] != V.EMPTY ? x : x - shiftX; + enpassantMove.vanish.push({ + x: px, + y: epsq.y, + p: "p", + c: this.getColor(px, epsq.y) + }); + moves.push(enpassantMove); + } + } + } + return moves; + } + +}; diff --git a/client/src/variants/Pandemonium.js b/client/src/variants/Pandemonium2.js similarity index 78% rename from client/src/variants/Pandemonium.js rename to client/src/variants/Pandemonium2.js index 4894ec16..7951608a 100644 --- a/client/src/variants/Pandemonium.js +++ b/client/src/variants/Pandemonium2.js @@ -2,7 +2,15 @@ import { ChessRules, Move, PiPo } from "@/base_rules"; import { randInt } from "@/utils/alea"; import { ArrayFun } from "@/utils/array"; -export class PandemoniumRules extends ChessRules { +export class Pandemonium2Rules extends ChessRules { + + static get PawnSpecs() { + return Object.assign( + { }, + ChessRules.PawnSpecs, + { promotions: [V.GILDING] } + ); + } loseOnRepetition() { // If current side is under check: lost @@ -55,7 +63,7 @@ export class PandemoniumRules extends ChessRules { } static get size() { - return { x: 10, y: 10}; + return { x: 8, y: 10}; } getColor(i, j) { @@ -97,17 +105,6 @@ export class PandemoniumRules extends ChessRules { }; } - static IsGoodEnpassant(enpassant) { - if (enpassant != "-") { - const squares = enpassant.split(","); - if (squares.length > 2) return false; - for (let sq of squares) { - if (!sq.match(/[a-j0-9]/)) return false; - } - } - return true; - } - static IsGoodFen(fen) { if (!ChessRules.IsGoodFen(fen)) return false; const fenParsed = V.ParseFen(fen); @@ -145,7 +142,7 @@ export class PandemoniumRules extends ChessRules { static GenRandInitFen(randomness) { if (randomness == 0) { return ( - "rnbqkmcbnr/pppppppppp/91/91/91/91/91/91/PPPPPPPPPP/RNBQKMCBNR " + + "rnbqkmcbnr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNBQKMCBNR " + "w 0 ajaj - 00000000000000" ); } @@ -212,48 +209,6 @@ export class PandemoniumRules extends ChessRules { ); } - getEnpassantFen() { - const L = this.epSquares.length; - if (!this.epSquares[L - 1]) return "-"; //no en-passant - let res = ""; - this.epSquares[L - 1].forEach(sq => { - res += V.CoordsToSquare(sq) + ","; - }); - return res.slice(0, -1); //remove last comma - } - - getEpSquare(moveOrSquare) { - if (!moveOrSquare) return undefined; - if (typeof moveOrSquare === "string") { - const square = moveOrSquare; - if (square == "-") return undefined; - let res = []; - square.split(",").forEach(sq => { - res.push(V.SquareToCoords(sq)); - }); - return res; - } - // Argument is a move: - const move = moveOrSquare; - const [sx, sy, ex] = [move.start.x, move.start.y, move.end.x]; - if (this.getPiece(sx, sy) == V.PAWN && Math.abs(sx - ex) >= 2) { - const step = (ex - sx) / Math.abs(ex - sx); - let res = [{ - x: sx + step, - y: sy - }]; - if (sx + 2 * step != ex) { - // 3-squares jump - res.push({ - x: sx + 2 * step, - y: sy - }); - } - return res; - } - return undefined; //default - } - getReservePpath(index, color) { const p = V.RESERVE_PIECES[index]; const prefix = (ChessRules.PIECES.includes(p) ? "" : "Pandemonium/"); @@ -316,6 +271,19 @@ export class PandemoniumRules extends ChessRules { }; } + applyPromotions(moves, promoted) { + const lastRank = (this.turn == 'w' ? 0 : V.size.x - 1); + let promotions = []; + moves.forEach(m => { + if ([m.start.x, m.end.x].includes(lastRank)) { + let pMove = JSON.parse(JSON.stringify(m)); + pMove.appear[0].p = promoted; + promotions.push(pMove); + } + }); + Array.prototype.push.apply(moves, promotions); + } + getPotentialMovesFrom([x, y]) { const c = this.getColor(x, y); const oppCol = V.GetOppCol(c); @@ -331,12 +299,12 @@ export class PandemoniumRules extends ChessRules { }) ]; } - const firstRank = (this.movesCount == 0 ? 9 : 0); + const firstRank = (this.movesCount == 0 ? V.size.x - 1 : 0); if (x != firstRank || this.getPiece(x, y) != V.KNIGHT) return []; // Swap with who? search for matching bishop: let knights = [], bishops = []; - for (let i = 0; i < 10; i++) { + for (let i = 0; i < V.size.y; i++) { const elt = this.board[x][i][1]; if (elt == 'n') knights.push(i); else if (elt == 'b') bishops.push(i); @@ -404,73 +372,8 @@ export class PandemoniumRules extends ChessRules { break; } // Maybe apply promotions: - if (Object.keys(V.PromoteMap).includes(p)) { - const promoted = V.PromoteMap[p]; - const lastRanks = (c == 'w' ? [0, 1] : [9, 8]); - let promotions = []; - moves.forEach(m => { - if (lastRanks.includes(m.start.x) || lastRanks.includes(m.end.x)) { - let pMove = JSON.parse(JSON.stringify(m)); - pMove.appear[0].p = promoted; - promotions.push(pMove); - } - }); - Array.prototype.push.apply(moves, promotions); - } - return moves; - } - - addPawnMoves([x1, y1], [x2, y2], moves) { - const color = this.turn; - const lastRanks = (color == "w" ? [0, 1] : [9, 8]); - if (!lastRanks.includes(x2)) { - moves.push(this.getBasicMove([x1, y1], [x2, y2])); - return; - } - let finalPieces = [V.GILDING]; - if (x2 == lastRanks[1]) finalPieces.push(V.PAWN); - for (let piece of finalPieces) { - const tr = (piece != V.PAWN ? { c: color, p: piece } : null); - moves.push(this.getBasicMove([x1, y1], [x2, y2], tr)); - } - } - - getPotentialPawnMoves([x, y]) { - const color = this.turn; - const shiftX = (color == 'w' ? -1 : 1); - let moves = []; - if (this.board[x + shiftX][y] == V.EMPTY) { - this.addPawnMoves([x, y], [x + shiftX, y], moves); - if ((color == 'w' && x >= V.size.x - 3) || (color == 'b' && x <= 2)) { - if (this.board[x + 2 * shiftX][y] == V.EMPTY) { - moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y])); - if ( - ( - (color == 'w' && x == V.size.x - 2) || - (color == 'b' && x == 1) - ) - && - this.board[x + 3 * shiftX][y] == V.EMPTY - ) { - moves.push(this.getBasicMove([x, y], [x + 3 * shiftX, y])); - } - } - } - } - for (let shiftY of [-1, 1]) { - if (y + shiftY >= 0 && y + shiftY < V.size.y) { - if ( - this.board[x + shiftX][y + shiftY] != V.EMPTY && - this.canTake([x, y], [x + shiftX, y + shiftY]) - ) { - this.addPawnMoves([x, y], [x + shiftX, y + shiftY], moves); - } - } - } - Array.prototype.push.apply( - moves, - this.getEnpassantCaptures([x, y], shiftX) - ); + if (Object.keys(V.PromoteMap).includes(p)) + this.applyPromotions(moves, V.PromoteMap[p]); return moves; } @@ -502,31 +405,6 @@ export class PandemoniumRules extends ChessRules { this.getSlideNJumpMoves(sq, V.steps[V.BISHOP], "oneStep")); } - getEnpassantCaptures([x, y], shiftX) { - const Lep = this.epSquares.length; - const epSquare = this.epSquares[Lep - 1]; - let moves = []; - if (!!epSquare) { - for (let epsq of epSquare) { - // TODO: some redundant checks - if (epsq.x == x + shiftX && Math.abs(epsq.y - y) == 1) { - let enpassantMove = this.getBasicMove([x, y], [epsq.x, epsq.y]); - // WARNING: the captured pawn may be diagonally behind us, - // if it's a 3-squares jump and we take on 1st passing square - const px = this.board[x][epsq.y] != V.EMPTY ? x : x - shiftX; - enpassantMove.vanish.push({ - x: px, - y: epsq.y, - p: "p", - c: this.getColor(px, epsq.y) - }); - moves.push(enpassantMove); - } - } - } - return moves; - } - getPotentialKingMoves(sq) { // Initialize with normal moves let moves = this.getSlideNJumpMoves( diff --git a/client/src/variants/Stealthbomb.js b/client/src/variants/Stealthbomb1.js similarity index 97% rename from client/src/variants/Stealthbomb.js rename to client/src/variants/Stealthbomb1.js index ee73ef54..dce7f5a9 100644 --- a/client/src/variants/Stealthbomb.js +++ b/client/src/variants/Stealthbomb1.js @@ -1,6 +1,6 @@ import { ChessRules, Move, PiPo } from "@/base_rules"; -export class StealthbombRules extends ChessRules { +export class Stealthbomb1Rules extends ChessRules { static get CanAnalyze() { return false; @@ -84,7 +84,7 @@ export class StealthbombRules extends ChessRules { this.movesCount >= 2 || ( (c == 'w' && square[0] < 6) || - (c == 'b' && square[0] > 2) + (c == 'b' && square[0] > 1) ) ) { return null; @@ -94,7 +94,8 @@ export class StealthbombRules extends ChessRules { return new Move({ appear: [ new PiPo({ x: x, y: y, c: c, p: V.BOMB_CODE[piece] }) ], vanish: [ new PiPo({ x: x, y: y, c: c, p: piece }) ], - start: { x: -1, y: -1 } + start: { x: -1, y: -1 }, + end: { x: x, y: y, noHighlight: true } }); } diff --git a/client/src/variants/Stealthbomb2.js b/client/src/variants/Stealthbomb2.js new file mode 100644 index 00000000..613a5c28 --- /dev/null +++ b/client/src/variants/Stealthbomb2.js @@ -0,0 +1,27 @@ +import { Move, PiPo } from "@/base_rules"; +import { Stealthbomb1Rules } from "@/variants/Stealthbomb1"; + +export class Stealthbomb2Rules extends Stealthbomb1Rules { + + // Initiate the game by choosing a square for the bomb: + doClick(square) { + const c = this.turn; + if ( + this.movesCount >= 2 || + ( + (c == 'w' && square[0] != 6) || + (c == 'b' && square[0] != 1) + ) + ) { + return null; + } + const [x, y] = square; + return new Move({ + appear: [ new PiPo({ x: x, y: y, c: c, p: 's' }) ], + vanish: [ new PiPo({ x: x, y: y, c: c, p: 'p' }) ], + start: { x: -1, y: -1 }, + end: { x: x, y: y, noHighlight: true } + }); + } + +}; diff --git a/client/src/variants/Wildebeest.js b/client/src/variants/Wildebeest.js index a49da9b2..93353f9e 100644 --- a/client/src/variants/Wildebeest.js +++ b/client/src/variants/Wildebeest.js @@ -112,10 +112,12 @@ export class WildebeestRules extends ChessRules { const [sizeX, sizeY] = [V.size.x, V.size.y]; const shiftX = color == "w" ? -1 : 1; const startRanks = color == "w" ? [sizeX - 2, sizeX - 3] : [1, 2]; - const lastRank = color == "w" ? 0 : sizeX - 1; - const finalPieces = x + shiftX == lastRank - ? [V.WILDEBEEST, V.QUEEN] - : [V.PAWN]; + const lastRanks = color == "w" ? [0, 1] : [sizeX - 1, sizeX -2]; + let finalPieces = [V.PAWN]; + if (x + shiftX == lastRanks[1]) + Array.prototype.push.apply(finalPieces, [V.WILDEBEEST, V.QUEEN]); + else if (x + shiftX == lastRanks[0]) + finalPieces = [V.WILDEBEEST, V.QUEEN]; if (this.board[x + shiftX][y] == V.EMPTY) { // One square forward diff --git a/server/db/populate.sql b/server/db/populate.sql index 13a4fb8a..e7e7b702 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -122,7 +122,8 @@ insert or ignore into Variants (name, description) values ('Pacifist1', 'Convert & support (v1)'), ('Pacifist2', 'Convert & support (v2)'), ('Pacosako', 'Dance with the King'), - ('Pandemonium', 'Noise and confusion'), + ('Pandemonium1', 'Noise and confusion (v1)'), + ('Pandemonium2', 'Noise and confusion (v2)'), ('Parachute', 'Landing on the board'), ('Pawnmassacre', 'Pieces upside down'), ('Pawns', 'Reach the last rank (v1)'), @@ -156,7 +157,8 @@ insert or ignore into Variants (name, description) values ('Spartan', 'Spartan versus Persians'), ('Squatter1', 'Squat last rank (v1)'), ('Squatter2', 'Squat last rank (v2)'), - ('Stealthbomb', 'Beware the bomb'), + ('Stealthbomb1', 'Beware the bomb (v1)'), + ('Stealthbomb2', 'Beware the bomb (v2)'), ('Suicide', 'Lose all pieces'), ('Suction', 'Attract opposite king'), ('Swap', 'Dangerous captures'), -- 2.44.0