From e88d69a8735e334b681cdad380af53e2ff574d1f Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Tue, 5 May 2020 23:35:47 +0200 Subject: [PATCH] Add Freecapture + advance on Koopa Chess --- client/src/translations/en.js | 2 + client/src/translations/es.js | 2 + client/src/translations/fr.js | 2 + .../src/translations/rules/Freecapture/en.pug | 24 +++ .../src/translations/rules/Freecapture/es.pug | 24 +++ .../src/translations/rules/Freecapture/fr.pug | 24 +++ client/src/variants/Freecapture.js | 12 ++ client/src/variants/Koopa.js | 139 ++++++++++++++++++ server/db/populate.sql | 2 + 9 files changed, 231 insertions(+) create mode 100644 client/src/translations/rules/Freecapture/en.pug create mode 100644 client/src/translations/rules/Freecapture/es.pug create mode 100644 client/src/translations/rules/Freecapture/fr.pug create mode 100644 client/src/variants/Freecapture.js create mode 100644 client/src/variants/Koopa.js diff --git a/client/src/translations/en.js b/client/src/translations/en.js index 59d409b9..0d1f0b94 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -171,6 +171,7 @@ export const translations = { "Both sides of the mirror": "Both sides of the mirror", "Burmese chess": "Burmese chess", "Capture all of a kind": "Capture all of a kind", + "Capture both colors": "Capture both colors", "Capture en passant": "Capture en passant", "Capture on the edge": "Capture on the edge", "Capture powers": "Capture powers", @@ -243,6 +244,7 @@ export const translations = { "Shoot pieces": "Shoot pieces", "Squares disappear": "Squares disappear", "Standard rules": "Standard rules", + "Stun & kick pieces": "Stun & kick pieces", "Thai Chess": "Thai Chess", "The colorbound clobberers": "The colorbound clobberers", "The end of the world": "The end of the world", diff --git a/client/src/translations/es.js b/client/src/translations/es.js index e702b325..d7fef9b1 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -171,6 +171,7 @@ export const translations = { "Both sides of the mirror": "Ambos lados del espejo", "Burmese chess": "Ajedrez birmano", "Capture all of a kind": "Capturar todo del mismo tipo", + "Capture both colors": "Captura ambos colores", "Capture en passant": "Capturar en passant", "Capture on the edge": "Capturar en el borde", "Capture powers": "Capturar los poderes", @@ -243,6 +244,7 @@ export const translations = { "Shoot pieces": "Tirar de las piezas", "Squares disappear": "Las casillas desaparecen", "Standard rules": "Reglas estandar", + "Stun & kick pieces": "Aturdir & patear piezas", "Thai Chess": "Ajedrez tailandés", "The colorbound clobberers": "Los batidores unicolor", "The end of the world": "El fin del mundo", diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index 980742a3..d66ba0b4 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -171,6 +171,7 @@ export const translations = { "Both sides of the mirror": "Les deux côté du miroir", "Burmese chess": "Échecs birmans", "Capture all of a kind": "Capturez tout d'un même type", + "Capture both colors": "Capturer les deux couleurs", "Capture en passant": "Capturer en passant", "Capture on the edge": "Capturer sur le bord", "Capture powers": "Capturer les pouvoirs", @@ -243,6 +244,7 @@ export const translations = { "Shoot pieces": "Tirez sur les pièces", "Squares disappear": "Les cases disparaissent", "Standard rules": "Règles usuelles", + "Stun & kick pieces": "Étourdissez & frappez les pièces", "Thai Chess": "Échecs thai", "The colorbound clobberers": "Les tabasseurs unicolores", "The end of the world": "La fin du monde", diff --git a/client/src/translations/rules/Freecapture/en.pug b/client/src/translations/rules/Freecapture/en.pug new file mode 100644 index 00000000..ad38fb0a --- /dev/null +++ b/client/src/translations/rules/Freecapture/en.pug @@ -0,0 +1,24 @@ +p.boxed. + Pieces can capture both colors. + +p. + This can be useful to open lines for attack, and it also eliminate + back rank mate threats for example. + On the diagram 1.Qh5 is possible because 1...Ra1+ 2.Kxh2. + +figure.diagram-container + .diagram.diag12 + | fen:r5k1/5ppp/8/6N1/8/8/6PP/3Q3K: + .diagram.diag22 + | fen:r5k1/5ppp/8/6NQ/8/8/6PP/7K: + figcaption Before and after 1.Qh5 + +h3 Source + +p + |This variant is mentioned in + a(href="https://www.jsbeasley.co.uk/encyc.htm") + | The Classified Encyclopedia of Chess Variants + | . + +p Inventor: L. Tabi (1971) diff --git a/client/src/translations/rules/Freecapture/es.pug b/client/src/translations/rules/Freecapture/es.pug new file mode 100644 index 00000000..a236b2f1 --- /dev/null +++ b/client/src/translations/rules/Freecapture/es.pug @@ -0,0 +1,24 @@ +p.boxed. + Las piezas pueden capturar ambos colores. + +p. + Esto puede ser útil para abrir líneas de ataque, por ejemplo, y que + también elimina las amenazas de mate del corredor, por ejemplo. + En el diagrama 1.Qh5 es posible porque 1...Ra1+ 2.Kxh2. + +figure.diagram-container + .diagram.diag12 + | fen:r5k1/5ppp/8/6N1/8/8/6PP/3Q3K: + .diagram.diag22 + | fen:r5k1/5ppp/8/6NQ/8/8/6PP/7K: + figcaption Antes y después 1.Qh5 + +h3 Fuente + +p + | Esta variante se menciona en + a(href="https://www.jsbeasley.co.uk/encyc.htm") + | The Classified Encyclopedia of Chess Variants + | . + +p Inventor: L. Tabi (1971) diff --git a/client/src/translations/rules/Freecapture/fr.pug b/client/src/translations/rules/Freecapture/fr.pug new file mode 100644 index 00000000..1d8622dd --- /dev/null +++ b/client/src/translations/rules/Freecapture/fr.pug @@ -0,0 +1,24 @@ +p.boxed. + Les pièces peuvent capturer les deux couleurs. + +p. + Cela peut être utile pour ouvrir des lignes d'attaque par exemple, et ça + élimine aussi les menaces de mat du couloir par exemple. + Sur le diagramme 1.Qh5 est possible car 1...Ra1+ 2.Kxh2. + +figure.diagram-container + .diagram.diag12 + | fen:r5k1/5ppp/8/6N1/8/8/6PP/3Q3K: + .diagram.diag22 + | fen:r5k1/5ppp/8/6NQ/8/8/6PP/7K: + figcaption Before and after 1.Qh5 + +h3 Source + +p + | Cette variante est mentionnée dans + a(href="https://www.jsbeasley.co.uk/encyc.htm") + | The Classified Encyclopedia of Chess Variants + | . + +p Inventeur : L. Tabi (1971) diff --git a/client/src/variants/Freecapture.js b/client/src/variants/Freecapture.js new file mode 100644 index 00000000..19098b6d --- /dev/null +++ b/client/src/variants/Freecapture.js @@ -0,0 +1,12 @@ +import { ChessRules } from "@/base_rules"; + +export class FreecaptureRules extends ChessRules { + canTake() { + // Can capture both colors: + return true; + } + + static get SEARCH_DEPTH() { + return 2; + } +}; diff --git a/client/src/variants/Koopa.js b/client/src/variants/Koopa.js new file mode 100644 index 00000000..9ca83848 --- /dev/null +++ b/client/src/variants/Koopa.js @@ -0,0 +1,139 @@ +import { ChessRulesi, PiPo } from "@/base_rules"; + +export class KoopaRules extends ChessRules { + static get HasEnpassant() { + return false; + } + + // Between stun time and stun + 1 move + static get STUNNED_1() { + return ['s', 'u', 'o', 'c', 't', 'l']; + } + + // Between stun + 1 move and stun + 2 moves + static get STUNNED_2() { + return ['v', 'x', 'a', 'd', 'w', 'm']; + } + + static get PIECES() { + return ChessRules.PIECES.concat(V.STUNNED_1).concat(V.STUNNED_2); + } + + getNormalizedStep(step) { + const [deltaX, deltaY] = [Math.abs(step[0]), Math.abs(step[1])]; + if (deltaX == 0 || deltaY == 0 || deltaX == deltaY) + return [step[0] / deltaX || 0, step[1] / deltaY || 0]; + // Knight: + const divisor = Math.min(deltaX, deltaY) + return [step[0] / divisor, step[1] / divisor]; + } + + getPotentialMovesFrom([x, y]) { + let moves = super.getPotentialMovesFrom([x, y]); + // Complete moves: stuns & kicks + const stun = V.STUNNED_1.concat(V.STUNNED_2); + moves.forEach(m => { + if (m.vanish.length == 2 && m.appear.length == 1) { + const step = + this.getNormalizedStep([m.end.x - m.start.x, m.end.y - m.start.y]); + // "Capture" something: is target stunned? + if (stun.includes(m.vanish[1].p)) { + // Kick it: continue movement in the same direction, + // destroying all on its path. + let [i, j] = [m.end.x + step[0], m.end.y + step[1]]; + while (V.OnBoard(i, j)) { + if (this.board[i][j] != V.EMPTY) { + m.vanish.push( + new PiPo({ + x: i, + y: j, + c: this.getColor(i, j), + p: this.getPiece(i, j) + }) + ); + } + i += step[0]; + j += step[1]; + } + } + else { + // The piece is now stunned + m.appear.push(m.vanish.pop()); + const pIdx = ChessRules.PIECES.findIndex(p => p == m.appear[1].p); + m.appear[1].p = V.STUNNED_1[pIdx]; + // And the capturer continue in the same direction until an empty + // square or the edge of the board, maybe stunning other pieces. + let [i, j] = [m.end.x + step[0], m.end.y + step[1]]; + while (V.OnBoard(i, j) && this.board[i][j] != V.EMPTY) { + const colIJ = this.getColor(i, j); + const pieceIJ = this.getPiece(i, j); + m.vanish.push( + new PiPo({ + x: i, + y: j, + c: colIJ, + p: pieceIJ + }) + ); + const pIdx = ChessRules.PIECES.findIndex(p => p == pieceIJ); + m.appear.push( + new PiPo({ + x: i, + y: j, + c: colIJ, + p: V.STUNNED_1[pIdx] + }) + ); + i += step[0]; + j += step[1]; + } + if (V.OnBoard(i, j)) { + m.appear[0].x = i; + m.appear[0].y = j; + // Is it a pawn on last rank? + } + else { + // The piece is out + m.appear.shift(); + } + } + } + }); + return moves; + } + + static GenRandInitFen(randomness) { + // No en-passant: + return ChessRules.GenRandInitFen(randomness).slice(0, -2); + } + + filterValid(moves) { + // Forbid kicking own king out + const color = this.turn; + return moves.filter(m => { + return m.vanish.every(v => v.c != color || !(['l','m'].includes(v.p))); + }); + } + + getCheckSquares() { + return []; + } + + getCurrentScore() { + if (this.kingPos['w'][0] < 0) return "0-1"; + if (this.kingPos['b'][0] < 0) return "1-0"; + if (!this.atLeastOneMove()) return "1/2"; + return "*"; + } + + postPlay(move) { + // TODO: toutes les pièces "stunned" by me (turn) avancent d'un niveau + // --> alter board + move.wasStunned = array of stunned stage 2 pieces (just back to normal then) + } + + postUndo(move) { + if (wasStunned + STUNNED_2 + } +}; diff --git a/server/db/populate.sql b/server/db/populate.sql index a4b2b9a5..29595571 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -47,6 +47,7 @@ insert or ignore into Variants (name, description) values ('Enpassant', 'Capture en passant'), ('Extinction', 'Capture all of a kind'), ('Football', 'Score a goal'), + ('Freecapture', 'Capture both colors'), ('Grand', 'Big board'), ('Grasshopper', 'Long jumps over pieces'), ('Gridolina', 'Jump the borders'), @@ -57,6 +58,7 @@ insert or ignore into Variants (name, description) values ('Knightmate', 'Mate the knight'), ('Knightrelay1', 'Move like a knight (v1)'), ('Knightrelay2', 'Move like a knight (v2)'), + ('Koopa', 'Stun & kick pieces'), ('Koth', 'King of the Hill'), ('Losers', 'Get strong at self-mate'), ('Madrasi', 'Paralyzed pieces'), -- 2.44.0