From: Benjamin Auder Date: Mon, 28 Dec 2020 19:57:08 +0000 (+0100) Subject: Implement Wildebeest castling rule (well... almost correct) X-Git-Url: https://git.auder.net/doc/current/bundles/framework/images/%7B%7B%20targetUrl%20%7D%7D?a=commitdiff_plain;h=83cecc0fec143a6eac6f6632048d99398bd4c0da;p=vchess.git Implement Wildebeest castling rule (well... almost correct) --- diff --git a/TODO b/TODO index bb5989e8..227683d7 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ -Implement Wildebeest castle rules -=> (1, 2, 3 or 4 squares slide; randomized: may be impossible >1, but possible >4...) - Embedded rules language not updated when language is set (in Analyse, Game and Problems) If new live game starts in background, "new game" notify OK but not first move (not too serious however) On smartphone for Teleport, Chakart, Weiqi and some others: option "confirm moves on touch screen" diff --git a/client/public/images/pieces/Wildebeest/castle.svg b/client/public/images/pieces/Wildebeest/castle.svg new file mode 120000 index 00000000..97a07ec4 --- /dev/null +++ b/client/public/images/pieces/Wildebeest/castle.svg @@ -0,0 +1 @@ +../Coregal/castle.svg \ No newline at end of file diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue index 1d650ac0..d45f33b8 100644 --- a/client/src/components/Board.vue +++ b/client/src/components/Board.vue @@ -402,10 +402,12 @@ export default { this.choices = []; this.play(m); }; + const stopPropagation = (e) => { e.stopPropagation(); } const onClick = this.mobileBrowser - ? { touchend: applyMove } - : { mouseup: applyMove }; + // Must cancel mousedown logic: + ? { touchstart: stopPropagation, touchend: applyMove } + : { mousedown: stopPropagation, mouseup: applyMove }; return h( "div", { diff --git a/client/src/translations/rules/Wildebeest/en.pug b/client/src/translations/rules/Wildebeest/en.pug index 7d9dd396..aee7cbf0 100644 --- a/client/src/translations/rules/Wildebeest/en.pug +++ b/client/src/translations/rules/Wildebeest/en.pug @@ -19,17 +19,13 @@ figure.diagram-container h3 Special moves p. - Castling is possible as in orthodox 8x8 game. The white king move to c1 or j1 - (one square to the left of bottom-right corner) for large (resp. small) - castle. Same for black on the other side. + Castling is possible, and more flexible than in orthodox game: + the king can slide any number of (free) squares toward the rook, + which will end next to him on the other side. p. - Promotion occurs when pawns reach last rank. - They can only transform into a queen or a wildebeest. - -p. - Note: the castling rule is more restrictive than described in the original - rules. The game seems OK like that, but this may change in the future. + When a pawn reaches last rank, it can promote + into a queen or a wildebeest (only). h3 Source diff --git a/client/src/translations/rules/Wildebeest/es.pug b/client/src/translations/rules/Wildebeest/es.pug index 76af898a..9b4580dd 100644 --- a/client/src/translations/rules/Wildebeest/es.pug +++ b/client/src/translations/rules/Wildebeest/es.pug @@ -20,17 +20,12 @@ figure.diagram-container h3 Movimientos especiales p. - El enroque es posible como en un juego de ajedrez ortodoxo 8x8. - El rey blanco va a c1 o j1 (un cuadro a la izquierda de la esquina inferior - derecha) para un enroque grande (resp. pequeño). Lo mismo para las negras - del otro lado. + El enroque es posible y más flexible que en el juego ortodoxo: + 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. - Nota: la regla de enroque es más restrictiva que la descrita por las reglas - originales. El juego se ve bien así, pero puede cambiar algún día. - h3 Fuente p diff --git a/client/src/translations/rules/Wildebeest/fr.pug b/client/src/translations/rules/Wildebeest/fr.pug index 3736086c..63ccdabd 100644 --- a/client/src/translations/rules/Wildebeest/fr.pug +++ b/client/src/translations/rules/Wildebeest/fr.pug @@ -20,19 +20,14 @@ figure.diagram-container h3 Coups spéciaux p. - Le roque est possible comme dans une partie d'échecs orthodoxe 8x8. - Le roi blanc va en c1 ou j1 (une case à gauche du coin inférieur droit). - pour un grand (resp. petit) roque. Pareil pour les noirs de l'autre côté. + Le roque est possible, et plus souple que dans le jeu orthodoxe : + le roi peut sauter d'un nombre quelconque de cases (libres) vers la tour, + qui se retrouvera à côté de lui de l'autre côté. p. Un pion arrivé sur la dernière rangée se promeut en une dame ou un gnou seulement. -p. - Note : la règle du roque est plus restrictive que celle décrite par les - règles originelles. Le jeu semble OK comme ça, mais cela pourrait changer un - jour. - h3 Source p diff --git a/client/src/variants/Wildebeest.js b/client/src/variants/Wildebeest.js index 7a9e35c4..a2fc6148 100644 --- a/client/src/variants/Wildebeest.js +++ b/client/src/variants/Wildebeest.js @@ -1,4 +1,4 @@ -import { ChessRules } from "@/base_rules"; +import { ChessRules, Move, PiPo } from "@/base_rules"; import { ArrayFun } from "@/utils/array"; import { sample, randInt } from "@/utils/alea"; @@ -190,6 +190,75 @@ export class WildebeestRules extends ChessRules { ); } + getPPpath(m) { + if ( + m.appear.length == 2 && m.vanish.length == 2 && + Math.abs(m.end.y - m.start.y) == 1 && + this.board[m.end.x][m.end.y] == V.EMPTY + ) { + // Castle, king moved by one square only, not directly onto rook + return "Wildebeest/castle"; + } + return super.getPPpath(m); + } + + // Special Wildebeest castling rules: + getCastleMoves([x, y]) { + const c = this.getColor(x, y); + const oppCol = V.GetOppCol(c); + let moves = []; + let i = 0; + const castlingKing = this.board[x][y].charAt(1); + castlingCheck: for ( + let castleSide = 0; + castleSide < 2; + castleSide++ //"large", then "small" + ) { + if (this.castleFlags[c][castleSide] >= V.size.y) continue; + // Rook and king are on initial position + const rookPos = this.castleFlags[c][castleSide]; + const range = (castleSide == 0 ? [rookPos, y] : [y, rookPos]); + + // King and rook must be connected: + for (let i = range[0] + 1; i <= range[1] - 1; i++) { + if (this.board[x][i] != V.EMPTY) continue castlingCheck; + } + const step = 2 * castleSide - 1; + // No attacks on the path of the king ? + for (let i = range[0]; i <= range[1]; i++) { + if (i != rookPos && this.isAttacked([x, i], oppCol)) + continue castlingCheck; + if (i != y) { + // Found a possible castle move: + moves.push( + new Move({ + appear: [ + new PiPo({ + x: x, + y: i, + p: V.KING, + c: c + }), + new PiPo({ + x: x, + y: i - step, + p: V.ROOK, + c: c + }) + ], + vanish: [ + new PiPo({ x: x, y: y, p: V.KING, c: c }), + new PiPo({ x: x, y: rookPos, p: V.ROOK, c: c }) + ] + }) + ); + } + } + } + + return moves; + } + isAttacked(sq, color) { return ( super.isAttacked(sq, color) ||