From b627d118ab41dccbda68f4523de8f063d0fa89df Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Sun, 1 Mar 2020 23:52:36 +0100 Subject: [PATCH] Fix some rules, complete rules translations --- client/src/base_rules.js | 12 ++- client/src/translations/en.js | 4 +- client/src/translations/es.js | 4 +- client/src/translations/fr.js | 4 +- client/src/translations/rules/Check3/en.pug | 10 +++ client/src/translations/rules/Check3/es.pug | 10 +++ client/src/translations/rules/Check3/fr.pug | 10 +++ .../src/translations/rules/Grasshopper/en.pug | 29 ++++++- .../src/translations/rules/Grasshopper/es.pug | 36 +++++++- .../src/translations/rules/Grasshopper/fr.pug | 36 +++++++- .../src/translations/rules/Hiddenqueen/en.pug | 26 +++++- .../src/translations/rules/Hiddenqueen/es.pug | 27 +++++- .../src/translations/rules/Hiddenqueen/fr.pug | 27 +++++- .../src/translations/rules/Knightmate/en.pug | 31 ++++++- .../src/translations/rules/Knightmate/es.pug | 34 +++++++- .../src/translations/rules/Knightmate/fr.pug | 34 +++++++- client/src/variants/Check3.js | 4 +- client/src/variants/Grasshopper.js | 50 +++++++++++ client/src/variants/Hiddenqueen.js | 87 ++++++++++++++++++- server/db/populate.sql | 4 +- 20 files changed, 453 insertions(+), 26 deletions(-) diff --git a/client/src/base_rules.js b/client/src/base_rules.js index 149bb4d2..5b335b0f 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -395,14 +395,12 @@ export const ChessRules = class ChessRules { ////////////////// // INITIALIZATION - constructor(fen) { - // In printDiagram() fen isn't supply because only getPpath() is used - if (fen) - this.re_init(fen); - } - // Fen string fully describes the game state - re_init(fen) { + constructor(fen) { + if (!fen) + // In printDiagram() fen isn't supply because only getPpath() is used + // TODO: find a better solution! + return; const fenParsed = V.ParseFen(fen); this.board = V.GetBoard(fenParsed.position); this.turn = fenParsed.turn[0]; //[0] to work with MarseilleRules diff --git a/client/src/translations/en.js b/client/src/translations/en.js index 190b4127..635e44ac 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -150,14 +150,13 @@ export const translations = { "In the shadow": "In the shadow", "Give three checks": "Give three checks", "Keep antiking in check": "Keep antiking in check", - "King crosses the board": "King crosses the board", + "Kings cross the board": "Kings cross the board", "Laws of attraction": "Laws of attraction", "Long jumps over pieces": "Long jumps over pieces", "Lose all pieces": "Lose all pieces", "Mate any piece": "Mate any piece", "Mate the knight": "Mate the knight", "Middle battle": "Middle battle", - "Move like a knight": "Move like a knight", "Move twice": "Move twice", "Neverending rows": "Neverending rows", "Pawns move diagonally": "Pawns move diagonally", @@ -169,5 +168,6 @@ export const translations = { "Shoot pieces": "Shoot pieces", "Squares disappear": "Squares disappear", "Standard rules": "Standard rules", + "The knight transfers its powers": "The knight transfers its powers", "Unidentified pieces": "Unidentified pieces" }; diff --git a/client/src/translations/es.js b/client/src/translations/es.js index 94b8390d..89f2d31d 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -150,14 +150,13 @@ export const translations = { "In the shadow": "En la sombra", "Give three checks": "Dar tres jaques", "Keep antiking in check": "Mantener el antirey en jaque", - "King crosses the board": "El rey cruza el tablero", + "Kings cross the board": "Los reyes cruzan el tablero", "Laws of attraction": "Las leyes de las atracciones", "Long jumps over pieces": "Saltos largos sobre las piezas", "Lose all pieces": "Perder todas las piezas", "Mate any piece": "Matar cualquier pieza", "Mate the knight": "Matar el caballo", "Middle battle": "Batalla media", - "Move like a knight": "Moverse como un caballo", "Move twice": "Mover dos veces", "Neverending rows": "Filas interminables", "Pawns move diagonally": "Peones se mueven en diagonal", @@ -169,5 +168,6 @@ export const translations = { "Shoot pieces": "Tirar de las piezas", "Squares disappear": "Las casillas desaparecen", "Standard rules": "Reglas estandar", + "The knight transfers its powers": "El caballo transfiere sus poderes", "Unidentified pieces": "Piezas no identificadas" }; diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index c5d82e92..cc3a7b56 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -150,14 +150,13 @@ export const translations = { "In the shadow": "Dans l'ombre", "Give three checks": "Donnez trois échecs", "Keep antiking in check": "Gardez l'antiroi en échec", - "King crosses the board": "Le roi traverse l'échiquier", + "Kings cross the board": "Les rois traversent l'échiquier", "Laws of attraction": "Les lois de l'attraction", "Long jumps over pieces": "Sauts longs par dessus les pièces", "Lose all pieces": "Perdez toutes les pièces", "Mate any piece": "Matez n'importe quelle pièce", "Mate the knight": "Matez le cavalier", "Middle battle": "Bataille du milieu", - "Move like a knight": "Bougez comme un cavalier", "Move twice": "Jouer deux coups", "Neverending rows": "Rangées sans fin", "Pawns move diagonally": "Les pions vont en diagonale", @@ -169,5 +168,6 @@ export const translations = { "Shoot pieces": "Tirez sur les pièces", "Squares disappear": "Les cases disparaissent", "Standard rules": "Règles usuelles", + "The knight transfers its powers": "Le cavalier transfère ses pouvoirs", "Unidentified pieces": "Pièces non identifiées" }; diff --git a/client/src/translations/rules/Check3/en.pug b/client/src/translations/rules/Check3/en.pug index b5013b6f..11d2441e 100644 --- a/client/src/translations/rules/Check3/en.pug +++ b/client/src/translations/rules/Check3/en.pug @@ -5,6 +5,16 @@ p. Orthodox rules apply, but giving three checks win the game. Since it is easier than checkmate, most games would end in this way. +p. + In the diagram position, 2.Bb5+ c6 3.Bxc6+ is an excellent + sacrifice because now only one check will give white victory. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR: + figcaption. + After the moves 1.e4 d6?? + h3 Source p diff --git a/client/src/translations/rules/Check3/es.pug b/client/src/translations/rules/Check3/es.pug index 1c0cf266..60197816 100644 --- a/client/src/translations/rules/Check3/es.pug +++ b/client/src/translations/rules/Check3/es.pug @@ -6,6 +6,16 @@ p. la partida. Es más fácil que de matar, entonces la mayoría de las partidas deberían terminar así. +p. + En la posición del diagrama, 2.Bb5+ c6 3.Bxc6+ es un excelente sacrificio, + porque ahora un solo jaque garantizará la victoria de las blancas. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR: + figcaption. + Despues de las jugadas 1.e4 d6?? + h3 Fuente p diff --git a/client/src/translations/rules/Check3/fr.pug b/client/src/translations/rules/Check3/fr.pug index 1195a59f..905be78f 100644 --- a/client/src/translations/rules/Check3/fr.pug +++ b/client/src/translations/rules/Check3/fr.pug @@ -6,6 +6,16 @@ p. la partie. C'est plus facile que de mater, donc la plupart des parties devraient s'achever ainsi. +p. + Dans la position du diagramme, 2.Bb5+ c6 3.Bxc6+ est un excellent sacrifice + car maintenant un unique échec assurera la victoire aux blancs. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR: + figcaption. + Après les coups 1.e4 d6?? + h3 Source p diff --git a/client/src/translations/rules/Grasshopper/en.pug b/client/src/translations/rules/Grasshopper/en.pug index 4f56997b..70c31a96 100644 --- a/client/src/translations/rules/Grasshopper/en.pug +++ b/client/src/translations/rules/Grasshopper/en.pug @@ -1 +1,28 @@ -p TODO +p.boxed + | A new piece appears: the grasshopper (G), jumping over a piece and landing right after. + +p. + Each player begins with eight grasshoppers between the first rank and the + pawns on the third rank. The grasshopper moves potentially in all + directions, but needs the help of a piece for its movement : + it jumps over the first encountered piece (of any color), + and land on the very next square. + This square must be either empty or occupied by an enemy piece (which is eaten). + +figure.diagram-container + .diagram + | fen:8/5g2/ppppp3/8/2G2k2/1PPP4/4R3/8 a2,c2,c7,f7,g4: + figcaption Possible grasshopper moves from c4. + +p. + Note: grasshopper moves are not symmetric. + On the diagram the black grasshopper cannot capture on c4. + +h3 Source + +p + a(href="https://www.chessvariants.com/dpieces.dir/grashopper.html") Grasshopper Chess + |  on chessvariants.com. + | This variant is also playable + a(href="https://greenchess.net/rules.php?v=grasshopper") on greenchess.net + |  (with a deterministic initial position). diff --git a/client/src/translations/rules/Grasshopper/es.pug b/client/src/translations/rules/Grasshopper/es.pug index 4f56997b..99bf70c7 100644 --- a/client/src/translations/rules/Grasshopper/es.pug +++ b/client/src/translations/rules/Grasshopper/es.pug @@ -1 +1,35 @@ -p TODO +p.boxed + | Aparece una nueva pieza: el saltamontes, saltando sobre una pieza + | aterrizar justo detrás. + +p. + Notación: 'G' como la primera carta de grasshopper, + que significa saltamontes en inglés. + +p. + Cada jugador comienza con ocho saltamontes colocadas entre las primeras + fila y los peones en el tercero. + El saltamontes se mueve potencialmente en todas las direcciones, + pero necesita la ayuda de una pieza para su movimiento: + el salta sobre la primera pieza encontrada (de cualquier color), + y aterriza en la casilla justo detrás. + Este última debe estar vacío u ocupado por el enemigo (que se encuentra comido). + +figure.diagram-container + .diagram + | fen:8/5g2/ppppp3/8/2G2k2/1PPP4/4R3/8 a2,c2,c7,f7,g4: + figcaption Posibles movimientos de saltamontes desde c4. + +p. + Nota: los movimientos de saltamontes no son simétricos. + En el diagrama, el saltamontes negro no puede capturar en c4. + +h3 Fuente + +p + | La + a(href="https://www.chessvariants.com/dpieces.dir/grashopper.html") variante Grasshopper + |  en chessvariants.com. + | También podemos jugarlo + a(href="https://greenchess.net/rules.php?v=grasshopper") en greenchess.net + |  (con una posición inicial determinista). diff --git a/client/src/translations/rules/Grasshopper/fr.pug b/client/src/translations/rules/Grasshopper/fr.pug index 4f56997b..650b41b8 100644 --- a/client/src/translations/rules/Grasshopper/fr.pug +++ b/client/src/translations/rules/Grasshopper/fr.pug @@ -1 +1,35 @@ -p TODO +p.boxed + | Une nouvelle pièce apparaît : la sauterelle, sautant par dessus une pièce + | pour atterrir juste derrière. + +p. + Notation: 'G' comme la première lettre de grasshopper, + signifiant sauterelle en anglais. + +p. + Chaque joueur commence avec huit sauterelles placées entre la première + rangée et les pions sur la troisième. + La sauterelle se déplace potentiellement dans toutes les directions, + mais a besoin de l'aide d'une pièce pour son mouvement : + elle saute par dessus la première pièce rencontrée (de n'importe quelle couleur), + et atterrit sur la case située juste derrière. + Cette dernière doit être vide ou occupée par l'ennemi (qui se retrouve mangé). + +figure.diagram-container + .diagram + | fen:8/5g2/ppppp3/8/2G2k2/1PPP4/4R3/8 a2,c2,c7,f7,g4: + figcaption Possibles coups de sauterelle depuis c4. + +p. + Note : les coups de sauterelles ne sont pas symétriques. + Sur le diagramme la sauterelle noire ne peut pas capturer en c4. + +h3 Source + +p + | La + a(href="https://www.chessvariants.com/dpieces.dir/grashopper.html") variante Grasshopper + |  sur chessvariants.com. + | On peut y jouer également + a(href="https://greenchess.net/rules.php?v=grasshopper") sur greenchess.net + |  (avec une position initiale déterministe). diff --git a/client/src/translations/rules/Hiddenqueen/en.pug b/client/src/translations/rules/Hiddenqueen/en.pug index 4f56997b..08c08c17 100644 --- a/client/src/translations/rules/Hiddenqueen/en.pug +++ b/client/src/translations/rules/Hiddenqueen/en.pug @@ -1 +1,25 @@ -p TODO +p.boxed + | One of the pawns of each side is a disguised queen. + | She is revealed only when not moving like a pawn. + +p. + The hidden queen cannot give check (because the opponent cannot see her nature), + but she could sometimes capture the king. This capture ends the game. + Except that, everything goes as in orthodox chess. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1tppp/8/3P4/8/8/TPPP1PPP/RNBQKBNR: + figcaption After 1.e4 d5 2.exd5 + +p. + In the diagram position, if the black hidden queen is on e7 then + they can play 2...Qxe1, revealing her identity and winning at the same time. + +h3 Source + +p + a(href="https://dames-cachees.herokuapp.com/rules") This website + |  introduces the rules and allow to play in live, + | with a deterministic initial position but a user-defined + | location of the hiden queen. diff --git a/client/src/translations/rules/Hiddenqueen/es.pug b/client/src/translations/rules/Hiddenqueen/es.pug index 4f56997b..de5a988b 100644 --- a/client/src/translations/rules/Hiddenqueen/es.pug +++ b/client/src/translations/rules/Hiddenqueen/es.pug @@ -1 +1,26 @@ -p TODO +p.boxed + | Uno de los peones de cada lado es en realidad una dama (disfrazada). + | Esta se revela cuando no se mueve como un peón. + +p. + La dama oculta no da jaque (porque el oponente no ve su naturaleza), + pero eventualmente puede capturar al rey. Esta captura termina el juego. + Aparte de eso, todo va como el ajedrez ortodoxo. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1tppp/8/3P4/8/8/TPPP1PPP/RNBQKBNR: + figcaption Después de 1.e4 d5 2.exd5 + +p. + En la posición del diagrama, si la dama negra escondida está en e7 + entonces pueden jugar 2...Dxe1, ciertamente revelando su identidad pero + ganando la victoria al pasar. + +h3 Fuente + +p + a(href = "https://dames-cachees.herokuapp.com/rules") Este sitio web + |  presenta las reglas y te permite jugar en vivo, + | con una posición inicial determinista pero dejando elegir + | la ubicación de la dama escondida diff --git a/client/src/translations/rules/Hiddenqueen/fr.pug b/client/src/translations/rules/Hiddenqueen/fr.pug index 4f56997b..33413715 100644 --- a/client/src/translations/rules/Hiddenqueen/fr.pug +++ b/client/src/translations/rules/Hiddenqueen/fr.pug @@ -1 +1,26 @@ -p TODO +p.boxed + | Un des pions de chaque camp est en réalité une dame (déguisée). + | Celle-ci est révélée lorsqu'elle ne se déplace pas comme un pion. + +p. + La dame cachée ne donne pas échec (car l'adversaire ne voit pas sa nature), + mais elle peut éventuellement capturer le roi. Cette capture met fin à la partie. + À part ça tout se déroule comme aux échecs orthodoxes. + +figure.diagram-container + .diagram + | fen:rnbqkbnr/ppp1tppp/8/3P4/8/8/TPPP1PPP/RNBQKBNR: + figcaption Après 1.e4 d5 2.exd5 + +p. + Dans la position du diagramme, si la dame cachée des noirs est en e7 + alors ils peuvent jouer 2...Dxe1, révélant certes son identité mais + emportant la victoire au passage. + +h3 Source + +p + a(href="https://dames-cachees.herokuapp.com/rules") Ce site web + |  présente les règles et permet de jouer en direct, + | avec une position initiale déterministe mais en laissant choisir + | l'emplacement de la dame cachée. diff --git a/client/src/translations/rules/Knightmate/en.pug b/client/src/translations/rules/Knightmate/en.pug index 4f56997b..565d25ee 100644 --- a/client/src/translations/rules/Knightmate/en.pug +++ b/client/src/translations/rules/Knightmate/en.pug @@ -1 +1,30 @@ -p TODO +p.boxed + | The king moves like a knight, and the knights like a king. + | The goal is still to checkmate the king. + +p "Knights moving like a king" are quite logically called "commoners". + +p Castling is still permitted, under the same conditions as in orthodox chess. + +figure.diagram-container + .diagram.diag12 + | fen:7k/8/8/8/8/1r6/8/3K1r2: + .diagram.diag22 + | fen:rcbqk1cr/pppp1ppp/8/2b1p3/2B1P3/5Q2/PPPP1PPP/RCB1K1CR: + figcaption. + Left: Royal knight version of the two-rooks mate. + Right: After 1.e4 e5 2.Bc4 Bc5 3.Qf3 + +p. + On the right diagram, the threat is 4.Bxf7+ Cxf7 5.Qxf7+, + with more material and a winning attack. + +h3 Source + +p + a(href="https://www.chessvariants.com/diffobjective.dir/knightmate.html") + | Knightmate Chess + |  on chessvariants.com. + | This variant is also playable + a(href="https://greenchess.net/rules.php?v=knightmate") on greenchess.net + |  (with a deterministic initial position). diff --git a/client/src/translations/rules/Knightmate/es.pug b/client/src/translations/rules/Knightmate/es.pug index 4f56997b..bdfaba99 100644 --- a/client/src/translations/rules/Knightmate/es.pug +++ b/client/src/translations/rules/Knightmate/es.pug @@ -1 +1,33 @@ -p TODO +p.boxed + | El rey se mueve como un caballo, y los caballos como reyes. + | El objetivo sigue siendo matar al rey. + +p. + Los "caballos que se mueven como reyes" son entonces lógicamente + llamado "plebeyos", señaló 'C' para "commoner" en inglés. + +p El enroque todavía es posible, bajo las mismas condiciones que el ajedrez ortodoxo + +figure.diagram-container + .diagram.diag12 + | fen:7k/8/8/8/8/1r6/8/3K1r2: + .diagram.diag22 + | fen:rcbqk1cr/pppp1ppp/8/2b1p3/2B1P3/5Q2/PPPP1PPP/RCB1K1CR: + figcaption. + Izquierda: versión "caballo real" del mate de las dos torres. + Derecha: después de 1.e4 e5 2.Bc4 Bc5 3.Qf3 + +p. + En el diagrama de la derecha, la amenaza es 4.Bxf7+ Cxf7 5.Qxf7+ + con la ventaja material y un ataque ganador. + +h3 Fuente + +p + | La + a(href="https://www.chessvariants.com/diffobjective.dir/knightmate.html") + | variante Knightmate + |  en chessvariants.com. + | También podemos jugarlo + a(href="https://greenchess.net/rules.php?v=knightmate") en greenchess.net + |  (con una posición inicial determinista). diff --git a/client/src/translations/rules/Knightmate/fr.pug b/client/src/translations/rules/Knightmate/fr.pug index 4f56997b..9704e924 100644 --- a/client/src/translations/rules/Knightmate/fr.pug +++ b/client/src/translations/rules/Knightmate/fr.pug @@ -1 +1,33 @@ -p TODO +p.boxed + | Le roi se déplace comme un cavalier, et les cavaliers comme des rois. + | l'objectif est encore de mater le roi. + +p. + Les "cavaliers se déplaçant comme des rois" sont alors assez logiquement + appelés des "roturiers", notés 'C' pour "commoner" en anglais. + +p Le roque est toujours possible, sous les mêmes conditions qu'aux échecs orthodoxes. + +figure.diagram-container + .diagram.diag12 + | fen:7k/8/8/8/8/1r6/8/3K1r2: + .diagram.diag22 + | fen:rcbqk1cr/pppp1ppp/8/2b1p3/2B1P3/5Q2/PPPP1PPP/RCB1K1CR: + figcaption. + Gauche : Version "cavalier royal" du mat des deux tours. + Droite : Après 1.e4 e5 2.Bc4 Bc5 3.Qf3 + +p. + Sur le diagramme de droite, la menace est 4.Bxf7+ Cxf7 5.Qxf7+ + avec l'avantage matériel et une attaque gagnante. + +h3 Source + +p + | La + a(href="https://www.chessvariants.com/diffobjective.dir/knightmate.html") + | variante Knightmate + |  sur chessvariants.com. + | On peut y jouer également + a(href="https://greenchess.net/rules.php?v=knightmate") sur greenchess.net + |  (avec une position initiale déterministe). diff --git a/client/src/variants/Check3.js b/client/src/variants/Check3.js index a4b292a4..ea5ab841 100644 --- a/client/src/variants/Check3.js +++ b/client/src/variants/Check3.js @@ -25,7 +25,9 @@ export const VariantRules = class Check3Rules extends ChessRules { } getPpath(b) { - if (b[1] == 'k' && this.checkFlags[b[0]] > 0) + // TODO: !!this.checkFlags condition for printDiagram, but clearly not good. + // This is just a temporary fix. + if (b[1] == 'k' && this.checkFlags && this.checkFlags[b[0]] > 0) return "Check3/" + b[0] + 'k_' + this.checkFlags[b[0]]; return b; } diff --git a/client/src/variants/Grasshopper.js b/client/src/variants/Grasshopper.js index 58b12406..8f24340a 100644 --- a/client/src/variants/Grasshopper.js +++ b/client/src/variants/Grasshopper.js @@ -3,6 +3,10 @@ import { ArrayFun } from "@/utils/array"; import { randInt } from "@/utils/alea"; export const VariantRules = class GrasshopperRules extends ChessRules { + static get HasEnpassant() { + return false; + } + static get GRASSHOPPER() { return "g"; } @@ -24,6 +28,51 @@ export const VariantRules = class GrasshopperRules extends ChessRules { } } + getPotentialPawnMoves([x, y]) { + const color = this.turn; + let moves = []; + const [sizeX, sizeY] = [V.size.x, V.size.y]; + const shiftX = color == "w" ? -1 : 1; + const lastRank = color == "w" ? 0 : sizeX - 1; + + const finalPieces = + x + shiftX == lastRank + ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN, V.GRASSHOPPER] + : [V.PAWN]; + if (this.board[x + shiftX][y] == V.EMPTY) { + // One square forward + for (let piece of finalPieces) { + moves.push( + this.getBasicMove([x, y], [x + shiftX, y], { + c: color, + p: piece + }) + ); + } + // No 2-squares jump + } + // Captures + for (let shiftY of [-1, 1]) { + if ( + y + shiftY >= 0 && + y + shiftY < sizeY && + this.board[x + shiftX][y + shiftY] != V.EMPTY && + this.canTake([x, y], [x + shiftX, y + shiftY]) + ) { + for (let piece of finalPieces) { + moves.push( + this.getBasicMove([x, y], [x + shiftX, y + shiftY], { + c: color, + p: piece + }) + ); + } + } + } + + return moves; + } + getPotentialGrasshopperMoves([x, y]) { let moves = []; // Look in every direction until an obstacle (to jump) is met @@ -86,6 +135,7 @@ export const VariantRules = class GrasshopperRules extends ChessRules { static GenRandInitFen() { return ChessRules.GenRandInitFen() + .replace("w 0 1111 -", "w 0 1111") .replace( "/pppppppp/8/8/8/8/PPPPPPPP/", "/gggggggg/pppppppp/8/8/PPPPPPPP/GGGGGGGG/" diff --git a/client/src/variants/Hiddenqueen.js b/client/src/variants/Hiddenqueen.js index fe34fb28..4f66894b 100644 --- a/client/src/variants/Hiddenqueen.js +++ b/client/src/variants/Hiddenqueen.js @@ -78,7 +78,7 @@ export const VariantRules = class HiddenqueenRules extends ChessRules { getPotentialMovesFrom([x, y]) { if (this.getPiece(x, y) == V.HIDDEN_QUEEN) { - const pawnMoves = super.getPotentialPawnMoves([x, y]); + const pawnMoves = this.getPotentialPawnMoves([x, y]); let queenMoves = super.getPotentialQueenMoves([x, y]); // Remove from queen moves those corresponding to a pawn move: queenMoves = queenMoves @@ -93,6 +93,83 @@ export const VariantRules = class HiddenqueenRules extends ChessRules { return super.getPotentialMovesFrom([x, y]); } + // TODO: find a more general way to describe pawn movements to avoid + // re-writing almost the same function for several variants. + getPotentialPawnMoves([x, y]) { + const color = this.turn; + const piece = this.getPiece(x, y); + let moves = []; + const [sizeX, sizeY] = [V.size.x, V.size.y]; + const shiftX = color == "w" ? -1 : 1; + const startRank = color == "w" ? sizeX - 2 : 1; + const lastRank = color == "w" ? 0 : sizeX - 1; + + const finalPieces = + x + shiftX == lastRank + ? piece == V.PAWN + ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN] + : [V.QUEEN] //hidden queen revealed + : piece; + if (this.board[x + shiftX][y] == V.EMPTY) { + // One square forward + for (let p of finalPieces) { + moves.push( + this.getBasicMove([x, y], [x + shiftX, y], { + c: color, + p: p + }) + ); + } + if ( + x == startRank && + this.board[x + 2 * shiftX][y] == V.EMPTY + ) { + // Two squares jump + moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y])); + } + } + // Captures + for (let shiftY of [-1, 1]) { + if ( + y + shiftY >= 0 && + y + shiftY < sizeY && + this.board[x + shiftX][y + shiftY] != V.EMPTY && + this.canTake([x, y], [x + shiftX, y + shiftY]) + ) { + for (let p of finalPieces) { + moves.push( + this.getBasicMove([x, y], [x + shiftX, y + shiftY], { + c: color, + p: p + }) + ); + } + } + } + + if (V.HasEnpassant) { + // En passant + const Lep = this.epSquares.length; + const epSquare = this.epSquares[Lep - 1]; //always at least one element + if ( + !!epSquare && + epSquare.x == x + shiftX && + Math.abs(epSquare.y - y) == 1 + ) { + let enpassantMove = this.getBasicMove([x, y], [epSquare.x, epSquare.y]); + enpassantMove.vanish.push({ + x: x, + y: epSquare.y, + p: "p", + c: this.getColor(x, epSquare.y) + }); + moves.push(enpassantMove); + } + } + + return moves; + } + getPossibleMovesFrom(sq) { this.side = this.turn; return this.filterValid(this.getPotentialMovesFrom(sq)); @@ -152,4 +229,12 @@ export const VariantRules = class HiddenqueenRules extends ChessRules { this.side = this.turn; return super.getComputerMove(); } + + getNotation(move) { + const notation = super.getNotation(move); + if (notation.charAt(0) == 'T') + // Do not reveal hidden queens + return notation.substr(1); + return notation; + } }; diff --git a/server/db/populate.sql b/server/db/populate.sql index 6ddedf69..60cd18e9 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -24,12 +24,12 @@ insert or ignore into Variants (name,description) values ('Hidden', 'Unidentified pieces'), ('Hiddenqueen', 'Queen disguised as a pawn'), ('Knightmate', 'Mate the knight'), - ('Knightrelay', 'Move like a knight'), + ('Knightrelay', 'The knight transfers its powers'), ('Losers', 'Lose all pieces'), ('Magnetic', 'Laws of attraction'), ('Marseille', 'Move twice'), ('Rifle', 'Shoot pieces'), - ('Royalrace', 'King crosses the board'), + ('Royalrace', 'Kings cross the board'), ('Recycle', 'Reuse pieces'), ('Shatranj', 'Ancient rules'), ('Suction', 'Attract opposite king'), -- 2.44.0