From: Benjamin Auder Date: Tue, 19 May 2020 19:45:52 +0000 (+0200) Subject: Fix parseInt() usage, rename Doubleorda --> Ordamirror, implement Clorange variant X-Git-Url: https://git.auder.net/js/css/doc/index.css?a=commitdiff_plain;h=e50a802531b99829c533f22ecd21e359e7e1e049;p=vchess.git Fix parseInt() usage, rename Doubleorda --> Ordamirror, implement Clorange variant --- diff --git a/TODO b/TODO index 0698ddfa..f4d2c505 100644 --- a/TODO +++ b/TODO @@ -3,11 +3,6 @@ Also: if new live game starts in background, "new game" notify OK but not first On smartphone for Teleport, Chakart, Weiqi and some others: option "confirm moves on touch screen" (=> comme pour corr) + option "confirm moves in corr games"? -Clorange: -Clockwork Orange Chess (Fergus Duniho, -1999). https://www.chessvariants.com/other.dir/clockworkorange.html -implem : pieces code, yellow/red, easy - https://www.chessvariants.com/difftaking.dir/replacement.html https://www.chessvariants.com/other.dir/pocket.html diff --git a/client/public/images/pieces/Clorange/bc.svg b/client/public/images/pieces/Clorange/bc.svg new file mode 120000 index 00000000..b30a26ad --- /dev/null +++ b/client/public/images/pieces/Clorange/bc.svg @@ -0,0 +1 @@ +../Alice/bc.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/bo.svg b/client/public/images/pieces/Clorange/bo.svg new file mode 120000 index 00000000..1200186b --- /dev/null +++ b/client/public/images/pieces/Clorange/bo.svg @@ -0,0 +1 @@ +../Alice/bo.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/bs.svg b/client/public/images/pieces/Clorange/bs.svg new file mode 120000 index 00000000..e8cf23a8 --- /dev/null +++ b/client/public/images/pieces/Clorange/bs.svg @@ -0,0 +1 @@ +../Alice/bs.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/bt.svg b/client/public/images/pieces/Clorange/bt.svg new file mode 120000 index 00000000..c517549b --- /dev/null +++ b/client/public/images/pieces/Clorange/bt.svg @@ -0,0 +1 @@ +../Alice/bt.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/bu.svg b/client/public/images/pieces/Clorange/bu.svg new file mode 120000 index 00000000..09e6ea3e --- /dev/null +++ b/client/public/images/pieces/Clorange/bu.svg @@ -0,0 +1 @@ +../Alice/bu.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/wc.svg b/client/public/images/pieces/Clorange/wc.svg new file mode 120000 index 00000000..d23af91d --- /dev/null +++ b/client/public/images/pieces/Clorange/wc.svg @@ -0,0 +1 @@ +../Alice/wc.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/wo.svg b/client/public/images/pieces/Clorange/wo.svg new file mode 120000 index 00000000..4a85712d --- /dev/null +++ b/client/public/images/pieces/Clorange/wo.svg @@ -0,0 +1 @@ +../Alice/wo.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/ws.svg b/client/public/images/pieces/Clorange/ws.svg new file mode 120000 index 00000000..659b2de0 --- /dev/null +++ b/client/public/images/pieces/Clorange/ws.svg @@ -0,0 +1 @@ +../Alice/ws.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/wt.svg b/client/public/images/pieces/Clorange/wt.svg new file mode 120000 index 00000000..447fc4fe --- /dev/null +++ b/client/public/images/pieces/Clorange/wt.svg @@ -0,0 +1 @@ +../Alice/wt.svg \ No newline at end of file diff --git a/client/public/images/pieces/Clorange/wu.svg b/client/public/images/pieces/Clorange/wu.svg new file mode 120000 index 00000000..c1403b33 --- /dev/null +++ b/client/public/images/pieces/Clorange/wu.svg @@ -0,0 +1 @@ +../Alice/wu.svg \ No newline at end of file diff --git a/client/src/base_rules.js b/client/src/base_rules.js index ee13d5eb..d219f78a 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -158,7 +158,7 @@ export const ChessRules = class ChessRules { // 2) Check turn if (!fenParsed.turn || !V.IsGoodTurn(fenParsed.turn)) return false; // 3) Check moves count - if (!fenParsed.movesCount || !(parseInt(fenParsed.movesCount) >= 0)) + if (!fenParsed.movesCount || !(parseInt(fenParsed.movesCount, 10) >= 0)) return false; // 4) Check flags if (V.HasFlags && (!fenParsed.flags || !V.IsGoodFlags(fenParsed.flags))) @@ -185,7 +185,7 @@ export const ChessRules = class ChessRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -232,7 +232,7 @@ export const ChessRules = class ChessRules { return { // NOTE: column is always one char => max 26 columns // row is counted from black side => subtraction - x: V.size.x - parseInt(sq.substr(1)), + x: V.size.x - parseInt(sq.substr(1), 10), y: sq[0].charCodeAt() - 97 }; } @@ -480,7 +480,7 @@ export const ChessRules = class ChessRules { let j = 0; for (let indexInRow = 0; indexInRow < rows[i].length; indexInRow++) { const character = rows[i][indexInRow]; - const num = parseInt(character); + const num = parseInt(character, 10); // If num is a number, just shift j: if (!isNaN(num)) j += num; // Else: something at position i,j @@ -512,7 +512,7 @@ export const ChessRules = class ChessRules { const fenParsed = V.ParseFen(fen); this.board = V.GetBoard(fenParsed.position); this.turn = fenParsed.turn; - this.movesCount = parseInt(fenParsed.movesCount); + this.movesCount = parseInt(fenParsed.movesCount, 10); this.setOtherVariables(fen); } @@ -536,7 +536,7 @@ export const ChessRules = class ChessRules { this.INIT_COL_KING["w"] = k; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index e7e097fb..cb65f033 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -87,6 +87,7 @@ export default { endgameMessage: "", orientation: "w", mode: "", + gameMode: "", score: "*", //'*' means 'unfinished' moves: [], cursor: -1, //index of the move just played @@ -298,7 +299,7 @@ export default { } else { // Exit analyze mode: - this.mode = this.gameMode ; + this.mode = this.gameMode; this.cursor = this.gameCursor; this.moves = this.gameMoves; let fen = this.game.fenStart; @@ -464,11 +465,11 @@ export default { this.stackToPlay.unshift(move); return; } - this.inPlay = true; if (this.mode == "analyze") this.toggleAnalyze(); if (this.cursor < this.moves.length - 1) // To play a received move, cursor must be at the end of the game: this.gotoEnd(); + this.inPlay = true; } // The board may show some possible moves: (TODO: bad solution) this.$refs["board"].resetCurrentAttempt(); diff --git a/client/src/components/MoveList.vue b/client/src/components/MoveList.vue index 6385ea0d..2e011b49 100644 --- a/client/src/components/MoveList.vue +++ b/client/src/components/MoveList.vue @@ -81,7 +81,7 @@ export default { document.getElementById("adjuster") .addEventListener("click", processModalClick); // Take full width on small screens: - let boardSize = parseInt(localStorage.getItem("boardSize")); + let boardSize = parseInt(localStorage.getItem("boardSize"), 10); if (!boardSize) { boardSize = window.innerWidth >= 768 diff --git a/client/src/data/challengeCheck.js b/client/src/data/challengeCheck.js index fbfb445c..7665f6f4 100644 --- a/client/src/data/challengeCheck.js +++ b/client/src/data/challengeCheck.js @@ -1,7 +1,7 @@ import { extractTime } from "@/utils/timeControl"; export function checkChallenge(c) { - const vid = parseInt(c.vid); + const vid = parseInt(c.vid, 10); if (isNaN(vid) || vid <= 0) return "Please select a variant"; const tc = extractTime(c.cadence); diff --git a/client/src/data/problemCheck.js b/client/src/data/problemCheck.js index d6b916cf..8ee101f3 100644 --- a/client/src/data/problemCheck.js +++ b/client/src/data/problemCheck.js @@ -1,5 +1,5 @@ export function checkProblem(p) { - const vid = parseInt(p.vid); + const vid = parseInt(p.vid, 10); if (isNaN(vid) || vid <= 0) return "Please select a variant"; if (!V.IsGoodFen(p.fen)) return "Errors in FEN"; diff --git a/client/src/store.js b/client/src/store.js index 0bfeeebb..45535f84 100644 --- a/client/src/store.js +++ b/client/src/store.js @@ -90,7 +90,7 @@ export const store = { hints: getItemDefaultTrue("hints"), highlight: getItemDefaultTrue("highlight"), gotonext: getItemDefaultTrue("gotonext"), - randomness: parseInt(localStorage.getItem("randomness")) + randomness: parseInt(localStorage.getItem("randomness"), 10) }; if (isNaN(this.state.settings.randomness)) // Default: random asymmetric diff --git a/client/src/translations/rules/Clorange/en.pug b/client/src/translations/rules/Clorange/en.pug index 3a33838b..26679f58 100644 --- a/client/src/translations/rules/Clorange/en.pug +++ b/client/src/translations/rules/Clorange/en.pug @@ -1,2 +1,31 @@ p.boxed - | TODO + | Captured pieces can be dropped later in the game, + | with or without capturing abilities. + +p Orthodox rules apply, with the following exceptions: +ul + li. + When a regular (resp. non-capturing) Chess piece is captured, it is + replaced with a non-capturing (resp. regular) counterpart of the same + color and given back to the player of that color, + who holds it in hand until he drops it on the board. + li. + A player who has a piece in hand may use his turn to place it on any + empty square on the board. Pawns cannot be dropped on the last rank. + +p Non-capturing units appear in yellow for white, and red for black. + +figure.diagram-container + .diagram + | fen:3nkr2/1pNSpp1b/1p1sq3/7p/rT1N1cPp/8/PPPPPP2/R1BB1KR1: + figcaption The black king must capture the non-capturing white pawn. + +h3 Source + +p + | Slightly simplified from + a(href="https://www.chessvariants.com/other.dir/clockworkorange.html") + | Clockwork Orange Chess + |  on chessvariants.com. + +p Inventor: Fergus Duniho (1999) diff --git a/client/src/translations/rules/Clorange/es.pug b/client/src/translations/rules/Clorange/es.pug index 3a33838b..a5a8c832 100644 --- a/client/src/translations/rules/Clorange/es.pug +++ b/client/src/translations/rules/Clorange/es.pug @@ -1,2 +1,34 @@ p.boxed - | TODO + | Las piezas capturadas se pueden soltar más adelante en el juego, + | con o sin capacidad de captura. + +p Se aplican reglas ortodoxas, con las siguientes excepciones: +ul + li. + Cuando se captura una pieza estándar (resp. sin-captura), es + reemplazado por una pieza sin-captura (resp. estándar) del mismo color + y regresó al jugador de ese color, que lo tiene en la mano hasta que él + decide ponerlo en el tablero. + li. + Un jugador con una pieza en reserva puede soltarlo en cualquier casilla + del tablero en lugar de hacer un movimiento. Los peones no pueden alcanzar + la última fila así. + +p. + Las unidades que no capturan aparecen en amarillo para las blancas, + y en rojo para las negras. + +figure.diagram-container + .diagram + | fen:3nkr2/1pNSpp1b/1p1sq3/7p/rT1N1cPp/8/PPPPPP2/R1BB1KR1: + figcaption El rey negro debe capturar el peón blanco sin-captura. + +h3 Fuente + +p + | Ligeramente simplificado desde + a(href="https://www.chessvariants.com/other.dir/clockworkorange.html") + | Clockwork Orange Chess + |  en chessvariants.com. + +p Inventor: Fergus Duniho (1999) diff --git a/client/src/translations/rules/Clorange/fr.pug b/client/src/translations/rules/Clorange/fr.pug index 3a33838b..1e8a4069 100644 --- a/client/src/translations/rules/Clorange/fr.pug +++ b/client/src/translations/rules/Clorange/fr.pug @@ -1,2 +1,34 @@ p.boxed - | TODO + | Les pièces capturées peuvent être parachutées plus tard dans la partie, + | avec ou sans capacité de capture. + +p Les règles orthodoxes s'appliquent, avec les exceptions suivantes : +ul + li. + Quand une pièce standard (resp. non-capturante) est capturée, elle est + remplacée par une pièce non-capturante (resp. standard) de la même couleur + et rendue au joueur de cette couleur, qui la garde en main jusqu'à ce qu'il + décide de la poser sur l'échiquier. + li. + Un joueur ayant une pièce en réserve peut la parachuter n'importe où sur + l'échiquier au lieu d'effectuer un coup. Les pions ne peuvent atteindre + la dernière rangée ainsi. + +p. + Les unités non-capturantes apparaissent en jaune pour les blancs, + et en rouge pour les noirs. + +figure.diagram-container + .diagram + | fen:3nkr2/1pNSpp1b/1p1sq3/7p/rT1N1cPp/8/PPPPPP2/R1BB1KR1: + figcaption le roi noir doit capturer le pion blanc non-capturant. + +h3 Source + +p + | Légèrement simplifié depuis + a(href="https://www.chessvariants.com/other.dir/clockworkorange.html") + | Clockwork Orange Chess + |  sur chessvariants.com. + +p Inventeur : Fergus Duniho (1999) diff --git a/client/src/translations/rules/Doubleorda/en.pug b/client/src/translations/rules/Ordamirror/en.pug similarity index 100% rename from client/src/translations/rules/Doubleorda/en.pug rename to client/src/translations/rules/Ordamirror/en.pug diff --git a/client/src/translations/rules/Doubleorda/es.pug b/client/src/translations/rules/Ordamirror/es.pug similarity index 100% rename from client/src/translations/rules/Doubleorda/es.pug rename to client/src/translations/rules/Ordamirror/es.pug diff --git a/client/src/translations/rules/Doubleorda/fr.pug b/client/src/translations/rules/Ordamirror/fr.pug similarity index 100% rename from client/src/translations/rules/Doubleorda/fr.pug rename to client/src/translations/rules/Ordamirror/fr.pug diff --git a/client/src/utils/printDiagram.js b/client/src/utils/printDiagram.js index aee1e96a..524e12bc 100644 --- a/client/src/utils/printDiagram.js +++ b/client/src/utils/printDiagram.js @@ -19,7 +19,7 @@ function getShadowArray(shadow) { let shadowArray = ArrayFun.init(V.size.x, V.size.y, false); const squares = shadow.split(","); for (let i = 0; i < squares.length; i++) { - const rownum = V.size.x - parseInt(squares[i]); + const rownum = V.size.x - parseInt(squares[i], 10); if (!isNaN(rownum)) { // Shadow a full row for (let i = 0; i < V.size.y; i++) shadowArray[rownum][i] = true; diff --git a/client/src/utils/squareId.js b/client/src/utils/squareId.js index 58ca0862..a54f1a5d 100644 --- a/client/src/utils/squareId.js +++ b/client/src/utils/squareId.js @@ -7,5 +7,5 @@ export function getSquareId(o) { // Inverse function export function getSquareFromId(id) { const idParts = id.split("-"); - return [parseInt(idParts[1]), parseInt(idParts[2])]; + return [parseInt(idParts[1], 10), parseInt(idParts[2], 10)]; } diff --git a/client/src/utils/timeControl.js b/client/src/utils/timeControl.js index c38d08b1..97d5ab6a 100644 --- a/client/src/utils/timeControl.js +++ b/client/src/utils/timeControl.js @@ -28,7 +28,7 @@ export function extractTime(cadence) { tcParts[0] += "m"; const mainTimeArray = tcParts[0].match(/^([0-9]+)([smhd]+)$/); if (!mainTimeArray) return null; - const mainTimeValue = parseInt(mainTimeArray[1]); + const mainTimeValue = parseInt(mainTimeArray[1], 10); const mainTimeUnit = mainTimeArray[2][0]; const mainTime = timeUnitToSeconds(mainTimeValue, mainTimeUnit); let increment = 0; @@ -38,7 +38,7 @@ export function extractTime(cadence) { tcParts[1] += "s"; const incrementArray = tcParts[1].match(/^([0-9]+)([smhd]+)$/); if (!incrementArray) return null; - const incrementValue = parseInt(incrementArray[1]); + const incrementValue = parseInt(incrementArray[1], 10); const incrementUnit = incrementArray[2][0]; // Increment unit cannot be larger than main unit: if (isLargerUnit(incrementUnit, mainTimeUnit)) return null; diff --git a/client/src/variants/Alice.js b/client/src/variants/Alice.js index 82ba6b79..61fcd015 100644 --- a/client/src/variants/Alice.js +++ b/client/src/variants/Alice.js @@ -72,7 +72,7 @@ export class AliceRules extends ChessRules { if (['K','k','L','l'].includes(row[i])) kings[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -101,7 +101,7 @@ export class AliceRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(rows[i].charAt(j)); + const num = parseInt(rows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Antiking1.js b/client/src/variants/Antiking1.js index ab86f69b..07dae26c 100644 --- a/client/src/variants/Antiking1.js +++ b/client/src/variants/Antiking1.js @@ -56,7 +56,7 @@ export class Antiking1Rules extends BerolinaRules { this.antikingPos["w"] = [i, k]; break; default: { - const num = parseInt(rows[i].charAt(j)); + const num = parseInt(rows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Antiking2.js b/client/src/variants/Antiking2.js index a7ec2a83..762ca5c8 100644 --- a/client/src/variants/Antiking2.js +++ b/client/src/variants/Antiking2.js @@ -43,7 +43,7 @@ export class Antiking2Rules extends ChessRules { this.antikingPos["w"] = [i, k]; break; default: { - const num = parseInt(rows[i].charAt(j)); + const num = parseInt(rows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Apocalypse.js b/client/src/variants/Apocalypse.js index 2439ae5d..77d17c0e 100644 --- a/client/src/variants/Apocalypse.js +++ b/client/src/variants/Apocalypse.js @@ -55,7 +55,7 @@ export class ApocalypseRules extends ChessRules { if (['P','p'].includes(row[i])) pawns[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -139,8 +139,8 @@ export class ApocalypseRules extends ChessRules { setFlags(fenflags) { this.penaltyFlags = { - 'w': parseInt(fenflags[0]), - 'b': parseInt(fenflags[1]) + 'w': parseInt(fenflags[0], 10), + 'b': parseInt(fenflags[1], 10) }; } diff --git a/client/src/variants/Arena.js b/client/src/variants/Arena.js index 7cfda1d0..62d2802a 100644 --- a/client/src/variants/Arena.js +++ b/client/src/variants/Arena.js @@ -25,7 +25,7 @@ export class ArenaRules extends ChessRules { if (['K','k','Q','q'].includes(row[i])) royals[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Ball.js b/client/src/variants/Ball.js index c9bdb339..056ec61b 100644 --- a/client/src/variants/Ball.js +++ b/client/src/variants/Ball.js @@ -105,7 +105,7 @@ export class BallRules extends ChessRules { if (withBall.includes(lowerRi)) ballCount++; sumElts++; } else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Baroque.js b/client/src/variants/Baroque.js index 1e02cdf7..4ff23a00 100644 --- a/client/src/variants/Baroque.js +++ b/client/src/variants/Baroque.js @@ -38,7 +38,7 @@ export class BaroqueRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(position[i].charAt(j)); + const num = parseInt(position[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Cannibal.js b/client/src/variants/Cannibal.js index 1a8a4518..bd5524f7 100644 --- a/client/src/variants/Cannibal.js +++ b/client/src/variants/Cannibal.js @@ -49,7 +49,7 @@ export class CannibalRules extends ChessRules { else if (kingWhiteCodes.includes(row[i])) kings['w']++; if (allPiecesCodes.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -74,7 +74,7 @@ export class CannibalRules extends ChessRules { const color = (piece.charCodeAt(0) <= 90 ? 'w' : 'b'); this.kingPos[color] = [i, k]; } else { - const num = parseInt(rows[i].charAt(j)); + const num = parseInt(rows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } k++; diff --git a/client/src/variants/Chakart.js b/client/src/variants/Chakart.js index 73d7cfc9..1d12e42e 100644 --- a/client/src/variants/Chakart.js +++ b/client/src/variants/Chakart.js @@ -148,7 +148,7 @@ export class ChakartRules extends ChessRules { if (['K', 'k', 'L', 'l'].includes(row[i])) kings[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -210,24 +210,25 @@ export class ChakartRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Initialize captured pieces' counts from FEN + const captured = + V.ParseFen(fen).captured.split("").map(x => parseInt(x, 10)); this.captured = { w: { - [V.PAWN]: parseInt(fenParsed.captured[0]), - [V.ROOK]: parseInt(fenParsed.captured[1]), - [V.KNIGHT]: parseInt(fenParsed.captured[2]), - [V.BISHOP]: parseInt(fenParsed.captured[3]), - [V.QUEEN]: parseInt(fenParsed.captured[4]), - [V.KING]: parseInt(fenParsed.captured[5]) + [V.PAWN]: captured[0], + [V.ROOK]: captured[1], + [V.KNIGHT]: captured[2], + [V.BISHOP]: captured[3], + [V.QUEEN]: captured[4], + [V.KING]: captured[5] }, b: { - [V.PAWN]: parseInt(fenParsed.captured[6]), - [V.ROOK]: parseInt(fenParsed.captured[7]), - [V.KNIGHT]: parseInt(fenParsed.captured[8]), - [V.BISHOP]: parseInt(fenParsed.captured[9]), - [V.QUEEN]: parseInt(fenParsed.captured[10]), - [V.KING]: parseInt(fenParsed.captured[11]) + [V.PAWN]: captured[6], + [V.ROOK]: captured[7], + [V.KNIGHT]: captured[8], + [V.BISHOP]: captured[9], + [V.QUEEN]: captured[10], + [V.KING]: captured[11] } }; this.firstMove = []; diff --git a/client/src/variants/Checkered1.js b/client/src/variants/Checkered1.js index 561f02f1..47e7375e 100644 --- a/client/src/variants/Checkered1.js +++ b/client/src/variants/Checkered1.js @@ -54,7 +54,7 @@ export class Checkered1Rules extends ChessRules { } // Stage 1: as Checkered2. Stage 2: checkered pieces are autonomous const stageInfo = V.ParseFen(fen).stage; - this.stage = parseInt(stageInfo[0]); + this.stage = parseInt(stageInfo[0], 10); this.sideCheckered = (this.stage == 2 ? stageInfo[1] : undefined); } diff --git a/client/src/variants/Clorange.js b/client/src/variants/Clorange.js index a9991316..4c54e941 100644 --- a/client/src/variants/Clorange.js +++ b/client/src/variants/Clorange.js @@ -2,15 +2,6 @@ import { ChessRules, PiPo, Move } from "@/base_rules"; import { ArrayFun } from "@/utils/array"; export class ClorangeRules extends ChessRules { - static get PawnSpecs() { - return Object.assign( - {}, - ChessRules.PawnSpecs, - // TODO: pawns reaching last rank promote normally? Seems better - { promotions: [V.PAWN] } - ); - } - static IsGoodFen(fen) { if (!ChessRules.IsGoodFen(fen)) return false; const fenParsed = V.ParseFen(fen); @@ -42,38 +33,64 @@ export class ClorangeRules extends ChessRules { } getReserveFen() { - let counts = new Array(10); - for ( - let i = 0; - i < V.PIECES.length - 1; - i++ //-1: no king reserve + return ( + Object.keys(this.reserve).map( + c => Object.values(this.reserve[c]).join("")).join("") + ); + } + + getEpSquare(moveOrSquare) { + if (!moveOrSquare) return undefined; + if (typeof moveOrSquare === "string") { + const square = moveOrSquare; + if (square == "-") return undefined; + return V.SquareToCoords(square); + } + const move = moveOrSquare; + const s = move.start, + e = move.end; + if ( + s.y == e.y && + Math.abs(s.x - e.x) == 2 && + move.vanish.length > 0 && ['p', 's'].includes(move.vanish[0].p) ) { - // TODO: adapt - counts[i] = this.reserve["w"][V.PIECES[i]]; - counts[5 + i] = this.reserve["b"][V.PIECES[i]]; + return { + x: (s.x + e.x) / 2, + y: s.y + }; } - return counts.join(""); + return undefined; } setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) - // TODO: adapt + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.KNIGHT]: parseInt(fenParsed.reserve[2]), - [V.BISHOP]: parseInt(fenParsed.reserve[3]), - [V.QUEEN]: parseInt(fenParsed.reserve[4]) + 'p': reserve[0], + 'r': reserve[1], + 'n': reserve[2], + 'b': reserve[3], + 'q': reserve[4], + 's': reserve[5], + 'u': reserve[6], + 'o': reserve[7], + 'c': reserve[8], + 't': reserve[9] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[5]), - [V.ROOK]: parseInt(fenParsed.reserve[6]), - [V.KNIGHT]: parseInt(fenParsed.reserve[7]), - [V.BISHOP]: parseInt(fenParsed.reserve[8]), - [V.QUEEN]: parseInt(fenParsed.reserve[9]) + 'p': reserve[10], + 'r': reserve[11], + 'n': reserve[12], + 'b': reserve[13], + 'q': reserve[14], + 's': reserve[15], + 'u': reserve[16], + 'o': reserve[17], + 'c': reserve[18], + 't': reserve[19] } }; } @@ -88,17 +105,27 @@ export class ClorangeRules extends ChessRules { return this.board[i][j].charAt(1); } + getPpath(b) { + return (V.NON_VIOLENT.includes(b[1]) ? "Clorange/" : "") + b; + } + getReservePpath(index, color) { - return color + V.RESERVE_PIECES[index]; + const prefix = + (V.NON_VIOLENT.includes(V.RESERVE_PIECES[index]) ? "Clorange/" : ""); + return prefix + color + V.RESERVE_PIECES[index]; } static get NON_VIOLENT() { - return ['s', 'u', 'o', 'c', 't', 'l']; + return ['s', 'u', 'o', 'c', 't']; + } + + static get PIECES() { + return ChessRules.PIECES.concat(V.NON_VIOLENT); } // Ordering on reserve pieces static get RESERVE_PIECES() { - return ChessRules.PIECES.concat(V.NON_VIOLENT); + return V.PIECES.filter(p => p != 'k'); } getReserveMoves([x, y]) { @@ -106,8 +133,13 @@ export class ClorangeRules extends ChessRules { const p = V.RESERVE_PIECES[y]; if (this.reserve[color][p] == 0) return []; let moves = []; - const pawnShift = p == V.PAWN ? 1 : 0; - for (let i = pawnShift; i < V.size.x - pawnShift; i++) { + let rank1 = 0; + let rank2 = V.size.x - 1; + if (['p', 's'].includes(p)) { + if (color == 'w') rank1++; + else rank2--; + } + for (let i = rank1; i <= rank2; i++) { for (let j = 0; j < V.size.y; j++) { if (this.board[i][j] == V.EMPTY) { let mv = new Move({ @@ -130,28 +162,52 @@ export class ClorangeRules extends ChessRules { return moves; } - // TODO: adapt all below: getPotentialMovesFrom([x, y]) { - if (x >= V.size.x) { + if (x >= V.size.x) // Reserves, outside of board: x == sizeX(+1) return this.getReserveMoves([x, y]); - } // Standard moves - return super.getPotentialMovesFrom([x, y]); + switch (this.getPiece(x, y)) { + case 's': return super.getPotentialPawnMoves([x, y]); + case 'u': return super.getPotentialRookMoves([x, y]); + case 'o': return super.getPotentialKnightMoves([x, y]); + case 'c': return super.getPotentialBishopMoves([x, y]); + case 't': return super.getPotentialQueenMoves([x, y]); + default: return super.getPotentialMovesFrom([x, y]); + } + return []; //never reached } - getPotentialPawnMoves([x, y]) { - - let moves = super.getPotentialPawnMoves([x, y]); - // Remove pawns on 8th rank ("fallen"): - const color = this.turn; - const lastRank = (color == "w" ? 0 : V.size.x - 1); + getPotentialPawnMoves(sq) { + let moves = super.getPotentialPawnMoves(sq); moves.forEach(m => { - if (m.appear[0].x == lastRank) m.appear.pop(); + if (m.vanish[0].p == 's' && m.appear[0].p != 's') { + // Promotion pieces should be non-violent as well: + const pIdx = ChessRules.PIECES.findIndex(p => p == m.appear[0].p) + m.appear[0].p = V.NON_VIOLENT[pIdx]; + } }); return moves; } + getSlideNJumpMoves([x, y], steps, oneStep) { + let moves = []; + const canTake = ChessRules.PIECES.includes(this.getPiece(x, y)); + outerLoop: for (let step of steps) { + let i = x + step[0]; + let j = y + step[1]; + while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { + moves.push(this.getBasicMove([x, y], [i, j])); + if (oneStep) continue outerLoop; + i += step[0]; + j += step[1]; + } + if (V.OnBoard(i, j) && canTake && this.canTake([x, y], [i, j])) + moves.push(this.getBasicMove([x, y], [i, j])); + } + return moves; + } + getAllValidMoves() { let moves = super.getAllPotentialMoves(); const color = this.turn; @@ -177,20 +233,22 @@ export class ClorangeRules extends ChessRules { return true; } - canTake([x1, y1], [x2, y2]) { - // Self-captures allowed, except for the king: - return this.getPiece(x2, y2) != V.KING; - } - prePlay(move) { super.prePlay(move); // Skip castle: if (move.vanish.length == 2 && move.appear.length == 2) return; const color = this.turn; if (move.vanish.length == 0) this.reserve[color][move.appear[0].p]--; - else if (move.vanish.length == 2 && move.vanish[1].c == color) - // Self-capture - this.reserve[color][move.vanish[1].p]++; + else if (move.vanish.length == 2) { + // Capture + const normal = ChessRules.PIECES.includes(move.vanish[1].p); + const pIdx = + normal + ? ChessRules.PIECES.findIndex(p => p == move.vanish[1].p) + : V.NON_VIOLENT.findIndex(p => p == move.vanish[1].p); + const rPiece = (normal ? V.NON_VIOLENT : ChessRules.PIECES)[pIdx]; + this.reserve[move.vanish[1].c][rPiece]++; + } } postUndo(move) { @@ -198,14 +256,34 @@ export class ClorangeRules extends ChessRules { if (move.vanish.length == 2 && move.appear.length == 2) return; const color = this.turn; if (move.vanish.length == 0) this.reserve[color][move.appear[0].p]++; - else if (move.vanish.length == 2 && move.vanish[1].c == color) - this.reserve[color][move.vanish[1].p]--; + else if (move.vanish.length == 2) { + const normal = ChessRules.PIECES.includes(move.vanish[1].p); + const pIdx = + normal + ? ChessRules.PIECES.findIndex(p => p == move.vanish[1].p) + : V.NON_VIOLENT.findIndex(p => p == move.vanish[1].p); + const rPiece = (normal ? V.NON_VIOLENT : ChessRules.PIECES)[pIdx]; + this.reserve[move.vanish[1].c][rPiece]--; + } } static get SEARCH_DEPTH() { return 2; } + static get VALUES() { + return Object.assign( + { + s: 0.75, + u: 4, + o: 2, + c: 2, + t: 7 + }, + ChessRules.VALUES + ); + } + evalPosition() { let evaluation = super.evalPosition(); // Add reserves: @@ -220,16 +298,12 @@ export class ClorangeRules extends ChessRules { getNotation(move) { const finalSquare = V.CoordsToSquare(move.end); if (move.vanish.length > 0) { - if (move.appear.length > 0) { - // Standard move - return super.getNotation(move); - } else { - // Pawn fallen: capturing or not - let res = ""; - if (move.vanish.length == 2) - res += V.CoordToColumn(move.start.y) + "x"; - return res + finalSquare; - } + // Standard move (maybe with non-violent piece) + let notation = super.getNotation(move); + if (move.vanish[0].p == 's' && move.appear[0].p != 's') + // Fix non-violent promotions: + notation += "=" + move.appear[0].p.toUpperCase(); + return notation; } // Rebirth: const piece = diff --git a/client/src/variants/Coregal.js b/client/src/variants/Coregal.js index d6c736f8..198cbfb0 100644 --- a/client/src/variants/Coregal.js +++ b/client/src/variants/Coregal.js @@ -37,7 +37,7 @@ export class CoregalRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } @@ -123,8 +123,10 @@ export class CoregalRules extends ChessRules { if (!!bishop1Options[pos]) delete bishop1Options[pos]; else if (!!bishop2Options[pos]) delete bishop2Options[pos]; }); - const bishop1Pos = parseInt(sample(Object.keys(bishop1Options), 1)[0]); - const bishop2Pos = parseInt(sample(Object.keys(bishop2Options), 1)[0]); + const bishop1Pos = + parseInt(sample(Object.keys(bishop1Options), 1)[0], 10); + const bishop2Pos = + parseInt(sample(Object.keys(bishop2Options), 1)[0], 10); // Knights' positions are now determined const forbidden = [ diff --git a/client/src/variants/Crazyhouse.js b/client/src/variants/Crazyhouse.js index 8e619743..ee485448 100644 --- a/client/src/variants/Crazyhouse.js +++ b/client/src/variants/Crazyhouse.js @@ -79,22 +79,23 @@ export class CrazyhouseRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.KNIGHT]: parseInt(fenParsed.reserve[2]), - [V.BISHOP]: parseInt(fenParsed.reserve[3]), - [V.QUEEN]: parseInt(fenParsed.reserve[4]) + [V.PAWN]: reserve[0], + [V.ROOK]: reserve[1], + [V.KNIGHT]: reserve[2], + [V.BISHOP]: reserve[3], + [V.QUEEN]: reserve[4] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[5]), - [V.ROOK]: parseInt(fenParsed.reserve[6]), - [V.KNIGHT]: parseInt(fenParsed.reserve[7]), - [V.BISHOP]: parseInt(fenParsed.reserve[8]), - [V.QUEEN]: parseInt(fenParsed.reserve[9]) + [V.PAWN]: reserve[5], + [V.ROOK]: reserve[6], + [V.KNIGHT]: reserve[7], + [V.BISHOP]: reserve[8], + [V.QUEEN]: reserve[9] } }; this.promoted = ArrayFun.init(V.size.x, V.size.y, false); diff --git a/client/src/variants/Extinction.js b/client/src/variants/Extinction.js index bdea80b5..db8abc06 100644 --- a/client/src/variants/Extinction.js +++ b/client/src/variants/Extinction.js @@ -16,7 +16,7 @@ export class ExtinctionRules extends ChessRules { let pieces = {}; for (let row of rows) { for (let i = 0; i < row.length; i++) { - if (isNaN(parseInt(row[i])) && !pieces[row[i]]) + if (isNaN(parseInt(row[i], 10)) && !pieces[row[i]]) pieces[row[i]] = true; } } diff --git a/client/src/variants/Football.js b/client/src/variants/Football.js index e7e65138..1ccb2a4d 100644 --- a/client/src/variants/Football.js +++ b/client/src/variants/Football.js @@ -44,7 +44,7 @@ export class FootballRules extends ChessRules { pieces[row[i] == lowerRi ? "b" : "w"]++; sumElts++; } else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Forward.js b/client/src/variants/Forward.js index 5c5b641d..8f2fc895 100644 --- a/client/src/variants/Forward.js +++ b/client/src/variants/Forward.js @@ -46,7 +46,7 @@ export class ForwardRules extends ChessRules { this.INIT_COL_KING["w"] = k; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Grand.js b/client/src/variants/Grand.js index b88410c9..14c0cc96 100644 --- a/client/src/variants/Grand.js +++ b/client/src/variants/Grand.js @@ -55,7 +55,8 @@ export class GrandRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const captured = V.ParseFen(fen).captured.split("").map(parseInt); + const captured = + V.ParseFen(fen).captured.split("").map(x => parseInt(x, 10)); // Initialize captured pieces' counts from FEN this.captured = { w: { diff --git a/client/src/variants/Hamilton.js b/client/src/variants/Hamilton.js index 6794e726..69dd9e5c 100644 --- a/client/src/variants/Hamilton.js +++ b/client/src/variants/Hamilton.js @@ -50,7 +50,7 @@ export class HamiltonRules extends ChessRules { for (let i = 0; i < row.length; i++) { if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Hidden.js b/client/src/variants/Hidden.js index f9455fd6..2d44df5c 100644 --- a/client/src/variants/Hidden.js +++ b/client/src/variants/Hidden.js @@ -94,7 +94,7 @@ export class HiddenRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Horde.js b/client/src/variants/Horde.js index aac4d27a..c436811b 100644 --- a/client/src/variants/Horde.js +++ b/client/src/variants/Horde.js @@ -24,7 +24,7 @@ export class HordeRules extends ChessRules { } sumElts++; } else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Interweave.js b/client/src/variants/Interweave.js index 8e0c3cc6..973797d6 100644 --- a/client/src/variants/Interweave.js +++ b/client/src/variants/Interweave.js @@ -56,7 +56,7 @@ export class InterweaveRules extends ChessRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -97,18 +97,19 @@ export class InterweaveRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); + const captured = + V.ParseFen(fen).captured.split("").map(x => parseInt(x, 10)); // Initialize captured pieces' counts from FEN this.captured = { w: { - [V.ROOK]: parseInt(fenParsed.captured[0]), - [V.KNIGHT]: parseInt(fenParsed.captured[1]), - [V.BISHOP]: parseInt(fenParsed.captured[2]), + [V.ROOK]: captured[0], + [V.KNIGHT]: captured[1], + [V.BISHOP]: captured[2] }, b: { - [V.ROOK]: parseInt(fenParsed.captured[3]), - [V.KNIGHT]: parseInt(fenParsed.captured[4]), - [V.BISHOP]: parseInt(fenParsed.captured[5]), + [V.ROOK]: captured[3], + [V.KNIGHT]: captured[4], + [V.BISHOP]: captured[5] } }; // Stack of "last move" only for intermediate captures diff --git a/client/src/variants/Kinglet.js b/client/src/variants/Kinglet.js index 38ca6492..518069f8 100644 --- a/client/src/variants/Kinglet.js +++ b/client/src/variants/Kinglet.js @@ -28,7 +28,7 @@ export class KingletRules extends ChessRules { if (lowerRi == 'p') pawns[row[i] == lowerRi ? "b" : "w"]++; sumElts++; } else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Koopa.js b/client/src/variants/Koopa.js index f24e5b2f..3f2e855a 100644 --- a/client/src/variants/Koopa.js +++ b/client/src/variants/Koopa.js @@ -49,11 +49,9 @@ export class KoopaRules extends ChessRules { } getStunnedFen() { - return ( - Object.keys(this.stunned) - .map(square => square + this.stunned[square]) - .join(",") - ); + const squares = Object.keys(this.stunned); + if (squares.length == 0) return "-"; + return squares.map(square => square + this.stunned[square]).join(","); } // Base GenRandInitFen() is fine because en-passant indicator will @@ -80,7 +78,7 @@ export class KoopaRules extends ChessRules { this.INIT_COL_KING["w"] = k; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } @@ -100,7 +98,7 @@ export class KoopaRules extends ChessRules { .map(s => { return { square: s.substr(0, 2), - state: parseInt(s[2]) + state: parseInt(s[2], 10) }; }); } diff --git a/client/src/variants/Maxima.js b/client/src/variants/Maxima.js index 83d20765..e8b15d25 100644 --- a/client/src/variants/Maxima.js +++ b/client/src/variants/Maxima.js @@ -49,7 +49,7 @@ export class MaximaRules extends ChessRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -76,7 +76,7 @@ export class MaximaRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(position[i].charAt(j)); + const num = parseInt(position[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Minishogi.js b/client/src/variants/Minishogi.js index 83152894..afeaa57e 100644 --- a/client/src/variants/Minishogi.js +++ b/client/src/variants/Minishogi.js @@ -42,22 +42,23 @@ export class MinishogiRules extends ShogiRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.BISHOP]: parseInt(fenParsed.reserve[2]), - [V.GOLD_G]: parseInt(fenParsed.reserve[3]), - [V.SILVER_G]: parseInt(fenParsed.reserve[4]) + [V.PAWN]: reserve[0], + [V.ROOK]: reserve[1], + [V.BISHOP]: reserve[2], + [V.GOLD_G]: reserve[3], + [V.SILVER_G]: reserve[4] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[5]), - [V.ROOK]: parseInt(fenParsed.reserve[6]), - [V.BISHOP]: parseInt(fenParsed.reserve[7]), - [V.GOLD_G]: parseInt(fenParsed.reserve[8]), - [V.SILVER_G]: parseInt(fenParsed.reserve[9]) + [V.PAWN]: reserve[5], + [V.ROOK]: reserve[6], + [V.BISHOP]: reserve[7], + [V.GOLD_G]: reserve[8], + [V.SILVER_G]: reserve[9] } }; } diff --git a/client/src/variants/Monochrome.js b/client/src/variants/Monochrome.js index b17b6f1f..31cf59ea 100644 --- a/client/src/variants/Monochrome.js +++ b/client/src/variants/Monochrome.js @@ -23,7 +23,7 @@ export class MonochromeRules extends ChessRules { for (let i = 0; i < row.length; i++) { if (V.PIECES.includes(row[i])) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Omega.js b/client/src/variants/Omega.js index 258bc807..1fde5821 100644 --- a/client/src/variants/Omega.js +++ b/client/src/variants/Omega.js @@ -48,7 +48,7 @@ export class OmegaRules extends ChessRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Doubleorda.js b/client/src/variants/Ordamirror.js similarity index 100% rename from client/src/variants/Doubleorda.js rename to client/src/variants/Ordamirror.js diff --git a/client/src/variants/Pacifist1.js b/client/src/variants/Pacifist1.js index 234b02a8..43c81d71 100644 --- a/client/src/variants/Pacifist1.js +++ b/client/src/variants/Pacifist1.js @@ -24,7 +24,7 @@ export class Pacifist1Rules extends ChessRules { if (['K','k'].includes(row[i])) kingsCount++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -52,7 +52,7 @@ export class Pacifist1Rules extends ChessRules { this.INIT_COL_KING["w"] = k; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Parachute.js b/client/src/variants/Parachute.js index 86b1ce84..8cd0f9c2 100644 --- a/client/src/variants/Parachute.js +++ b/client/src/variants/Parachute.js @@ -23,7 +23,7 @@ export class ParachuteRules extends ChessRules { for (let i = 0; i < row.length; i++) { if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } @@ -65,24 +65,25 @@ export class ParachuteRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.KNIGHT]: parseInt(fenParsed.reserve[2]), - [V.BISHOP]: parseInt(fenParsed.reserve[3]), - [V.QUEEN]: parseInt(fenParsed.reserve[4]), - [V.KING]: parseInt(fenParsed.reserve[5]) + [V.PAWN]: reserve[0], + [V.ROOK]: reserve[1], + [V.KNIGHT]: reserve[2], + [V.BISHOP]: reserve[3], + [V.QUEEN]: reserve[4], + [V.KING]: reserve[5] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[6]), - [V.ROOK]: parseInt(fenParsed.reserve[7]), - [V.KNIGHT]: parseInt(fenParsed.reserve[8]), - [V.BISHOP]: parseInt(fenParsed.reserve[9]), - [V.QUEEN]: parseInt(fenParsed.reserve[10]), - [V.KING]: parseInt(fenParsed.reserve[11]) + [V.PAWN]: reserve[6], + [V.ROOK]: reserve[7], + [V.KNIGHT]: reserve[8], + [V.BISHOP]: reserve[9], + [V.QUEEN]: reserve[10], + [V.KING]: reserve[11] } }; } diff --git a/client/src/variants/Recycle.js b/client/src/variants/Recycle.js index bf252632..d23a78c2 100644 --- a/client/src/variants/Recycle.js +++ b/client/src/variants/Recycle.js @@ -54,22 +54,23 @@ export class RecycleRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.KNIGHT]: parseInt(fenParsed.reserve[2]), - [V.BISHOP]: parseInt(fenParsed.reserve[3]), - [V.QUEEN]: parseInt(fenParsed.reserve[4]) + [V.PAWN]: reserve[0], + [V.ROOK]: reserve[1], + [V.KNIGHT]: reserve[2], + [V.BISHOP]: reserve[3], + [V.QUEEN]: reserve[4] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[5]), - [V.ROOK]: parseInt(fenParsed.reserve[6]), - [V.KNIGHT]: parseInt(fenParsed.reserve[7]), - [V.BISHOP]: parseInt(fenParsed.reserve[8]), - [V.QUEEN]: parseInt(fenParsed.reserve[9]) + [V.PAWN]: reserve[5], + [V.ROOK]: reserve[6], + [V.KNIGHT]: reserve[7], + [V.BISHOP]: reserve[8], + [V.QUEEN]: reserve[9] } }; } @@ -124,10 +125,9 @@ export class RecycleRules extends ChessRules { } getPotentialMovesFrom([x, y]) { - if (x >= V.size.x) { + if (x >= V.size.x) // Reserves, outside of board: x == sizeX(+1) return this.getReserveMoves([x, y]); - } // Standard moves return super.getPotentialMovesFrom([x, y]); } diff --git a/client/src/variants/Rococo.js b/client/src/variants/Rococo.js index e0838e14..e6480a8c 100644 --- a/client/src/variants/Rococo.js +++ b/client/src/variants/Rococo.js @@ -54,7 +54,7 @@ export class RococoRules extends ChessRules { this.kingPos["w"] = [i, k]; break; default: { - const num = parseInt(position[i].charAt(j)); + const num = parseInt(position[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } diff --git a/client/src/variants/Schess.js b/client/src/variants/Schess.js index 06644c7e..95118982 100644 --- a/client/src/variants/Schess.js +++ b/client/src/variants/Schess.js @@ -119,12 +119,12 @@ export class SchessRules extends ChessRules { const fenParsed = V.ParseFen(fen); this.pocket = { "w": { - h: parseInt(fenParsed.pocket[0]), - e: parseInt(fenParsed.pocket[1]) + h: parseInt(fenParsed.pocket[0], 10), + e: parseInt(fenParsed.pocket[1], 10) }, "b": { - h: parseInt(fenParsed.pocket[2]), - e: parseInt(fenParsed.pocket[3]) + h: parseInt(fenParsed.pocket[2], 10), + e: parseInt(fenParsed.pocket[3], 10) } }; } diff --git a/client/src/variants/Shogi.js b/client/src/variants/Shogi.js index 521e4680..6c522dc6 100644 --- a/client/src/variants/Shogi.js +++ b/client/src/variants/Shogi.js @@ -176,26 +176,27 @@ export class ShogiRules extends ChessRules { setOtherVariables(fen) { super.setOtherVariables(fen); - const fenParsed = V.ParseFen(fen); // Also init reserves (used by the interface to show landable pieces) + const reserve = + V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10)); this.reserve = { w: { - [V.PAWN]: parseInt(fenParsed.reserve[0]), - [V.ROOK]: parseInt(fenParsed.reserve[1]), - [V.BISHOP]: parseInt(fenParsed.reserve[2]), - [V.GOLD_G]: parseInt(fenParsed.reserve[3]), - [V.SILVER_G]: parseInt(fenParsed.reserve[4]), - [V.KNIGHT]: parseInt(fenParsed.reserve[5]), - [V.LANCE]: parseInt(fenParsed.reserve[6]) + [V.PAWN]: reserve[0], + [V.ROOK]: reserve[1], + [V.BISHOP]: reserve[2], + [V.GOLD_G]: reserve[3], + [V.SILVER_G]: reserve[4], + [V.KNIGHT]: reserve[5], + [V.LANCE]: reserve[6] }, b: { - [V.PAWN]: parseInt(fenParsed.reserve[7]), - [V.ROOK]: parseInt(fenParsed.reserve[8]), - [V.BISHOP]: parseInt(fenParsed.reserve[9]), - [V.GOLD_G]: parseInt(fenParsed.reserve[10]), - [V.SILVER_G]: parseInt(fenParsed.reserve[11]), - [V.KNIGHT]: parseInt(fenParsed.reserve[12]), - [V.LANCE]: parseInt(fenParsed.reserve[13]) + [V.PAWN]: reserve[7], + [V.ROOK]: reserve[8], + [V.BISHOP]: reserve[9], + [V.GOLD_G]: reserve[10], + [V.SILVER_G]: reserve[11], + [V.KNIGHT]: reserve[12], + [V.LANCE]: reserve[13] } }; } diff --git a/client/src/variants/Suicide.js b/client/src/variants/Suicide.js index 2693f84f..ecb2aef1 100644 --- a/client/src/variants/Suicide.js +++ b/client/src/variants/Suicide.js @@ -29,7 +29,7 @@ export class SuicideRules extends ChessRules { pieces[row[i] == lowerRi ? "b" : "w"]++; sumElts++; } else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Threechecks.js b/client/src/variants/Threechecks.js index 175b1246..05250596 100644 --- a/client/src/variants/Threechecks.js +++ b/client/src/variants/Threechecks.js @@ -11,7 +11,7 @@ export class ThreechecksRules extends ChessRules { this.checkFlags = { w: 0, b: 0 }; const flags = fenflags.substr(4); //skip first 4 digits, for castle for (let c of ["w", "b"]) { - this.checkFlags[c] = parseInt(flags.charAt(c == "w" ? 0 : 1)); + this.checkFlags[c] = parseInt(flags.charAt(c == "w" ? 0 : 1), 10); } } diff --git a/client/src/variants/Twokings.js b/client/src/variants/Twokings.js index 52aebc32..d56d0951 100644 --- a/client/src/variants/Twokings.js +++ b/client/src/variants/Twokings.js @@ -21,7 +21,7 @@ export class TwokingsRules extends CoregalRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/variants/Wormhole.js b/client/src/variants/Wormhole.js index cc9fd497..1f3ecd2a 100644 --- a/client/src/variants/Wormhole.js +++ b/client/src/variants/Wormhole.js @@ -39,7 +39,7 @@ export class WormholeRules extends ChessRules { if (['K','k'].includes(row[i])) kings[row[i]]++; if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; else { - const num = parseInt(row[i]); + const num = parseInt(row[i], 10); if (isNaN(num)) return false; sumElts += num; } diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index 6722f334..cd781a5d 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -1285,7 +1285,10 @@ console.log(data.data); // - from server (one correspondance game I play[ed] or not) // - from remote peer (one live game I don't play, finished or not) fetchGame: function(callback) { - if (Number.isInteger(this.gameRef) || !isNaN(parseInt(this.gameRef))) { + if ( + Number.isInteger(this.gameRef) || + !isNaN(parseInt(this.gameRef, 10)) + ) { // corr games identifiers are integers ajax( "/games", diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 146beb01..451299b7 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -240,12 +240,12 @@ export default { infoMessage: "", newchallenge: { fen: "", - vid: parseInt(localStorage.getItem("vid")) || 0, + vid: parseInt(localStorage.getItem("vid"), 10) || 0, to: "", //name of challenged player (if any) cadence: localStorage.getItem("cadence") || "", randomness: // Warning: randomness can be 0, then !!randomness is false - (parseInt(localStorage.getItem("challRandomness"))+1 || 3) - 1, + (parseInt(localStorage.getItem("challRandomness"),10)+1 || 3) - 1, // VariantRules object, stored to not interfere with // diagrams of targetted challenges: V: null, diff --git a/client/src/views/MyGames.vue b/client/src/views/MyGames.vue index 6835b556..5c3522ec 100644 --- a/client/src/views/MyGames.vue +++ b/client/src/views/MyGames.vue @@ -244,7 +244,7 @@ export default { case "notifyturn": case "notifyscore": { const info = data.data; - const type = (!!parseInt(info.gid) ? "corr" : "live"); + const type = (!!parseInt(info.gid, 10) ? "corr" : "live"); let game = gamesArrays[type].find(g => g.id == info.gid); // "notifything" --> "thing": const thing = data.code.substr(6); diff --git a/server/db/populate.sql b/server/db/populate.sql index 703297ae..60578f83 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -43,7 +43,6 @@ insert or ignore into Variants (name, description) values ('Doublearmy', '64 pieces on the board'), ('Doublemove1', 'Double moves (v1)'), ('Doublemove2', 'Double moves (v2)'), - ('Doubleorda', 'Mongolian Horde (v2)'), ('Dynamo', 'Push and pull'), ('Eightpieces', 'Each piece is unique'), ('Enpassant', 'Capture en passant'), @@ -73,6 +72,7 @@ insert or ignore into Variants (name, description) values ('Monster', 'White move twice'), ('Omega', 'A wizard in the corner'), ('Orda', 'Mongolian Horde (v1)'), + ('Ordamirror', 'Mongolian Horde (v2)'), ('Pacifist1', 'Convert & support (v1)'), ('Pacifist2', 'Convert & support (v2)'), ('Parachute', 'Landing on the board'),