From: Benjamin Auder Date: Tue, 18 Dec 2018 01:59:43 +0000 (+0100) Subject: Some refactoring in variants logic: more robust FEN handling (untested) X-Git-Url: https://git.auder.net/doc/html/app_dev.php/pieces/current/mini-custom.min.css?a=commitdiff_plain;h=2d7194bd9c976f444e43e5dc0a725823b6472eb9;p=vchess.git Some refactoring in variants logic: more robust FEN handling (untested) --- diff --git a/db/vchess.sqlite b/db/vchess.sqlite index 9d7e4a2a..f1d4f13e 100644 --- a/db/vchess.sqlite +++ b/db/vchess.sqlite @@ -1 +1 @@ -#$# git-fat 25d1d22208da0bc58bf3076bfe684bbcb98894b2 16384 +#$# git-fat 039e3c0aadcb97c144dc2d12a35aeb83b4a3849e 16384 diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index 620b86f8..ae0800cd 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -34,6 +34,10 @@ class ChessRules ////////////// // MISC UTILS + static get HasFlags() { return true; } //some variants don't have flags + + static get HasEnpassant() { return true; } //some variants don't have ep. + // Path to pieces static getPpath(b) { @@ -57,7 +61,34 @@ class ChessRules { const fenParsed = V.ParseFen(fen); // 1) Check position - const position = fenParsed.position; + if (!V.IsGoodPosition(fenParsed.position)) + return false; + // 2) Check turn + if (!fenParsed.turn || !["w","b"].includes(fenParsed.turn)) + return false; + // 3) Check flags + if (V.HasFlags && (!fenParsed.flags || !V.IsGoodFlags(fenParsed.flags))) + return false; + // 4) Check enpassant + if (V.HasEnpassant) + { + if (!fenParsed.enpassant) + return false; + if (fenParsed.enpassant != "-") + { + const ep = V.SquareToCoords(fenParsed.enpassant); + if (ep.y < 0 || ep.y > V.size.y || isNaN(ep.x) || ep.x < 0 || ep.x > V.size.x) + return false; + } + } + return true; + } + + // Is position part of the FEN a priori correct? + static IsGoodPosition(position) + { + if (position.length == 0) + return false; const rows = position.split("/"); if (rows.length != V.size.x) return false; @@ -79,19 +110,6 @@ class ChessRules if (sumElts != V.size.y) return false; } - // 2) Check flags (if present) - if (!!fenParsed.flags && !V.IsGoodFlags(fenParsed.flags)) - return false; - // 3) Check turn (if present) - if (!!fenParsed.turn && !["w","b"].includes(fenParsed.turn)) - return false; - // 4) Check enpassant (if present) - if (!!fenParsed.enpassant) - { - const ep = V.SquareToCoords(fenParsed.enpassant); - if (ep.y < 0 || ep.y > V.size.y || isNaN(ep.x) || ep.x < 0 || ep.x > V.size.x) - return false; - } return true; } @@ -101,6 +119,12 @@ class ChessRules return !!flags.match(/^[01]{4,4}$/); } + // 3 --> d (column letter from number) + static GetColumn(colnum) + { + return String.fromCharCode(97 + colnum); + } + // a4 --> {x:3,y:0} static SquareToCoords(sq) { @@ -113,7 +137,7 @@ class ChessRules // {x:0,y:4} --> e8 static CoordsToSquare(coords) { - return String.fromCharCode(97 + coords.y) + (V.size.x - coords.x); + return V.GetColumn(coords.y) + (V.size.x - coords.x); } // Aggregates flags into one object @@ -138,10 +162,7 @@ class ChessRules const square = moveOrSquare; if (square == "-") return undefined; - return { - x: square[0].charCodeAt()-97, - y: V.size.x-parseInt(square[1]) - }; + return V.SquareToCoords(square); } // Argument is a move: const move = moveOrSquare; @@ -246,19 +267,25 @@ class ChessRules static ParseFen(fen) { const fenParts = fen.split(" "); - return { + let res = + { position: fenParts[0], turn: fenParts[1], - flags: fenParts[2], - enpassant: fenParts[3], }; + let nextIdx = 2; + if (V.hasFlags) + Object.assign(res, {flags: fenParts[nextIdx++]}); + if (V.HasEnpassant) + Object.assign(res, {enpassant: fenParts[nextIdx]}); + return res; } // Return current fen (game state) getFen() { - return this.getBaseFen() + " " + this.turn + " " + - this.getFlagsFen() + " " + this.getEnpassantFen(); + return this.getBaseFen() + " " + this.turn + + (V.HasFlags ? (" " + this.getFlagsFen()) : "") + + (V.HasEnpassant ? (" " + this.getEnpassantFen()) : ""); } // Position part of the FEN string @@ -311,7 +338,7 @@ class ChessRules getEnpassantFen() { const L = this.epSquares.length; - if (L == 0) + if (!this.epSquares[L-1]) return "-"; //no en-passant return V.CoordsToSquare(this.epSquares[L-1]); } @@ -361,18 +388,13 @@ class ChessRules this.setOtherVariables(fen); } - // Some additional variables from FEN (variant dependant) - setOtherVariables(fen) + // Scan board for kings and rooks positions + scanKingsRooks(fen) { - // Set flags and enpassant: - const parsedFen = V.ParseFen(fen); - this.setFlags(fenParsed.flags); - this.epSquares = [ V.SquareToCoords(parsedFen.enpassant) ]; - // Search for king and rooks positions: this.INIT_COL_KING = {'w':-1, 'b':-1}; this.INIT_COL_ROOK = {'w':[-1,-1], 'b':[-1,-1]}; this.kingPos = {'w':[-1,-1], 'b':[-1,-1]}; //squares of white and black king - const fenRows = parsedFen.position.split("/"); + const fenRows = V.ParseFen(fen).position.split("/"); for (let i=0; i0 ? this.epSquares[Lep-1] : undefined); + const epSquare = this.epSquares[Lep-1]; //always at least one element if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1) { const epStep = epSquare.y - y; @@ -961,10 +1001,12 @@ class ChessRules if (!!ingame) move.notation = [this.getNotation(move), this.getLongNotation(move)]; - move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo) + if (V.HasFlags) + move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo) this.updateVariables(move); this.moves.push(move); - this.epSquares.push( this.getEpSquare(move) ); + if (V.HasEnpassant) + this.epSquares.push( this.getEpSquare(move) ); this.turn = this.getOppCol(this.turn); V.PlayOnBoard(this.board, move); @@ -979,10 +1021,12 @@ class ChessRules { V.UndoOnBoard(this.board, move); this.turn = this.getOppCol(this.turn); - this.epSquares.pop(); + if (V.HasEnpassant) + this.epSquares.pop(); this.moves.pop(); this.unupdateVariables(move); - this.disaggregateFlags(JSON.parse(move.flags)); + if (V.HasFlags) + this.disaggregateFlags(JSON.parse(move.flags)); // DEBUG: // if (this.getFen() != this.states[this.states.length-1]) diff --git a/public/javascripts/variants/Alice.js b/public/javascripts/variants/Alice.js index ece59cdc..00103a7b 100644 --- a/public/javascripts/variants/Alice.js +++ b/public/javascripts/variants/Alice.js @@ -29,24 +29,24 @@ class AliceRules extends ChessRules return (Object.keys(this.ALICE_PIECES).includes(b[1]) ? "Alice/" : "") + b; } - static get PIECES() { + static get PIECES() + { return ChessRules.PIECES.concat(Object.keys(V.ALICE_PIECES)); } - initVariables(fen) + setOtherVariables(fen) { - super.initVariables(fen); - const fenParts = fen.split(" "); - const position = fenParts[0].split("/"); + super.setOtherVariables(fen); + const rows = V.ParseFen(fen).position.split("/"); if (this.kingPos["w"][0] < 0 || this.kingPos["b"][0] < 0) { - // INIT_COL_XXX won't be used, so no need to set them for Alice kings - for (let i=0; i move.appear.length ? "x" : ""); let pawnMark = ""; if (["p","s"].includes(piece) && captureMark.length == 1) - pawnMark = String.fromCharCode(97 + move.start.y); //start column + pawnMark = V.GetColumn(move.start.y); //start column // Piece or pawn movement let notation = piece.toUpperCase() + pawnMark + captureMark + finalSquare; diff --git a/public/javascripts/variants/Antiking.js b/public/javascripts/variants/Antiking.js index 2b07cfbe..38cadf22 100644 --- a/public/javascripts/variants/Antiking.js +++ b/public/javascripts/variants/Antiking.js @@ -7,21 +7,22 @@ class AntikingRules extends ChessRules static get ANTIKING() { return 'a'; } - static get PIECES() { + static get PIECES() + { return ChessRules.PIECES.concat([V.ANTIKING]); } - initVariables(fen) + setOtherVariables(fen) { - super.initVariables(fen); + super.setOtherVariables(fen); this.antikingPos = {'w':[-1,-1], 'b':[-1,-1]}; - const position = fen.split(" ")[0].split("/"); - for (let i=0; i 1) { // Capture - let startColumn = String.fromCharCode(97 + move.start.y); + const startColumn = V.GetColumn(move.start.y); notation = startColumn + "x" + finalSquare + "=" + move.appear[0].p.toUpperCase(); } diff --git a/public/javascripts/variants/Crazyhouse.js b/public/javascripts/variants/Crazyhouse.js index bf47197d..00452cbd 100644 --- a/public/javascripts/variants/Crazyhouse.js +++ b/public/javascripts/variants/Crazyhouse.js @@ -1,31 +1,97 @@ class CrazyhouseRules extends ChessRules { - initVariables(fen) + static IsGoodFen(fen) { - super.initVariables(fen); - // Also init reserves (used by the interface to show landing pieces) + if (!ChessRules.IsGoodFen(fen)) + return false; + const fenParsed = V.ParseFen(fen); + // 5) Check reserves + if (!fenParsed.reserve || !fenParsed.reserve.match(/^[0-9]{10,10}$/)) + return false; + // 6) Check promoted array + if (!fenParsed.promoted) + return false; + fenpromoted = fenParsed.promoted; + if (fenpromoted == "-") + return true; //no promoted piece on board + const squares = fenpromoted.split(","); + for (let square of squares) + { + const c = V.SquareToCoords(square); + if (c.y < 0 || c.y > V.size.y || isNaN(c.x) || c.x < 0 || c.x > V.size.x) + return false; + } + return true; + } + + static GenRandInitFen() + { + const fen = ChessRules.GenRandInitFen(); + return fen.replace(" w 1111", " w 1111 0000000000 -"); + } + + getFen() + { + return super.getFen() + " " + this.getReserveFen() + " " + this.getPromotedFen(); + } + + getReserveFen() + { + let counts = _.map(_.range(10), 0); + for (let i=0; i 0) + res = res.slice(0,-1); //remove last comma + return res; + } + + setOtherVariables(fen) + { + super.setOtherVariables(fen); + const fenParsed = V.ParseFen(fen); + // Also init reserves (used by the interface to show landable pieces) this.reserve = { "w": { - [V.PAWN]: 0, - [V.ROOK]: 0, - [V.KNIGHT]: 0, - [V.BISHOP]: 0, - [V.QUEEN]: 0, + [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]), }, "b": { - [V.PAWN]: 0, - [V.ROOK]: 0, - [V.KNIGHT]: 0, - [V.BISHOP]: 0, - [V.QUEEN]: 0, + [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]), } }; this.promoted = doubleArray(V.size.x, V.size.y, false); - // May be a continuation: adjust numbers of pieces in reserve + promoted pieces - this.moves.forEach(m => { this.updateVariables(m); }); + for (let square of fenParsd.promoted.split(",")) + { + const [x,y] = V.SquareToCoords(square); + promoted[x][y] = true; + } } getColor(i,j) @@ -34,6 +100,7 @@ class CrazyhouseRules extends ChessRules return (i==V.size.x ? "w" : "b"); return this.board[i][j].charAt(0); } + getPiece(i,j) { if (i >= V.size.x) @@ -48,7 +115,8 @@ class CrazyhouseRules extends ChessRules } // Ordering on reserve pieces - static get RESERVE_PIECES() { + static get RESERVE_PIECES() + { return [V.PAWN,V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN]; } @@ -188,17 +256,13 @@ class CrazyhouseRules extends ChessRules // Rebirth: const piece = (move.appear[0].p != V.PAWN ? move.appear[0].p.toUpperCase() : ""); - const finalSquare = - String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x); - return piece + "@" + finalSquare; + return piece + "@" + V.CoordsToSquare(move.end); } getLongNotation(move) { if (move.vanish.length > 0) return super.getLongNotation(move); - const finalSquare = - String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x); - return "@" + finalSquare; + return "@" + V.CoordsToSquare(move.end); } } diff --git a/public/javascripts/variants/Extinction.js b/public/javascripts/variants/Extinction.js index 2b0aecaa..49d61b2d 100644 --- a/public/javascripts/variants/Extinction.js +++ b/public/javascripts/variants/Extinction.js @@ -1,27 +1,30 @@ class ExtinctionRules extends ChessRules { - initVariables(fen) + setOtherVariables(fen) { - super.initVariables(fen); + super.setOtherVariables(fen); + const pos = V.ParseFen(fen).position; + // NOTE: no need for safety "|| []", because each piece type must be present + // (otherwise game is already over!) this.material = { "w": { - [V.KING]: 1, - [V.QUEEN]: 1, - [V.ROOK]: 2, - [V.KNIGHT]: 2, - [V.BISHOP]: 2, - [V.PAWN]: 8 + [V.KING]: pos.match(/K/g).length, + [V.QUEEN]: pos.match(/Q/g).length, + [V.ROOK]: pos.match(/R/g).length, + [V.KNIGHT]: pos.match(/N/g).length, + [V.BISHOP]: pos.match(/B/g).length, + [V.PAWN]: pos.match(/P/g).length }, "b": { - [V.KING]: 1, - [V.QUEEN]: 1, - [V.ROOK]: 2, - [V.KNIGHT]: 2, - [V.BISHOP]: 2, - [V.PAWN]: 8 + [V.KING]: pos.match(/k/g).length, + [V.QUEEN]: pos.match(/q/g).length, + [V.ROOK]: pos.match(/r/g).length, + [V.KNIGHT]: pos.match(/n/g).length, + [V.BISHOP]: pos.match(/b/g).length, + [V.PAWN]: pos.match(/p/g).length } }; } @@ -117,7 +120,7 @@ class ExtinctionRules extends ChessRules checkGameEnd() { - return this.turn == "w" ? "0-1" : "1-0"; + return (this.turn == "w" ? "0-1" : "1-0"); } evalPosition() diff --git a/public/javascripts/variants/Grand.js b/public/javascripts/variants/Grand.js index 276acbc3..b598f2d2 100644 --- a/public/javascripts/variants/Grand.js +++ b/public/javascripts/variants/Grand.js @@ -7,10 +7,63 @@ class GrandRules extends ChessRules return ([V.MARSHALL,V.CARDINAL].includes(b[1]) ? "Grand/" : "") + b; } - initVariables(fen) + static IsGoodFen(fen) { - super.initVariables(fen); - this.captures = { "w": {}, "b": {} }; //for promotions + if (!ChessRules.IsGoodFen(fen)) + return false; + const fenParsed = V.ParseFen(fen); + // 5) Check captures + if (!fenParsed.captured || !fenParsed.captured.match(/^[0-9]{10,10}$/)) + return false; + return true; + } + + static GenRandInitFen() + { + const fen = ChessRules.GenRandInitFen(); + return fen.replace(" w 1111", " w 1111 0000000000"); + } + + getFen() + { + return super.getFen() + " " + this.getCapturedFen(); + } + + getCapturedFen() + { + let counts = _.map(_.range(10), 0); + for (let i=0; i { + res += V.CoordsToSquare(sq) + ","; + }); + return res.slice(0,-1); //remove last comma + } + // En-passant after 2-sq or 3-sq jumps - getEpSquare(move) + getEpSquare(moveOrSquare) { + if (!moveOrSquare) + return undefined; + if (typeof moveOrSquare === "string") + { + const square = moveOrSquare; + if (square == "-") + return undefined; + let res = []; + square.split(",").forEach(sq => { + res.push(V.SquareToCoords(sq)); + }); + return res; + } + // Argument is a move: + const move = moveOrSquare; const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x]; if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) >= 2) { @@ -104,7 +186,7 @@ class GrandRules extends ChessRules // Promotion let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN,V.MARSHALL,V.CARDINAL]; promotionPieces.forEach(p => { - if (!this.captures[color][p] || this.captures[color][p]==0) + if (this.captured[color][p]==0) return; // Normal move if (this.board[x+shift][y] == V.EMPTY) @@ -189,11 +271,8 @@ class GrandRules extends ChessRules super.updateVariables(move); if (move.vanish.length==2 && move.appear.length==1 && move.vanish[1].p != V.PAWN) { - // Capture: update this.captures - if (!this.captures[move.vanish[1].c][move.vanish[1].p]) - this.captures[move.vanish[1].c][move.vanish[1].p] = 1; - else - this.captures[move.vanish[1].c][move.vanish[1].p]++; + // Capture: update this.captured + this.captured[move.vanish[1].c][move.vanish[1].p]++; } } @@ -201,13 +280,11 @@ class GrandRules extends ChessRules { super.unupdateVariables(move); if (move.vanish.length==2 && move.appear.length==1 && move.vanish[1].p != V.PAWN) - { - this.captures[move.vanish[1].c][move.vanish[1].p] = - Math.max(0, this.captures[move.vanish[1].c][move.vanish[1].p]-1); - } + this.captured[move.vanish[1].c][move.vanish[1].p]--; } - static get VALUES() { + static get VALUES() + { return Object.assign( ChessRules.VALUES, {'c': 5, 'm': 7} //experimental @@ -216,7 +293,7 @@ class GrandRules extends ChessRules static get SEARCH_DEPTH() { return 2; } - // TODO: this function could be generalized and shared better + // TODO: this function could be generalized and shared better (how ?!...) static GenRandInitFen() { let pieces = { "w": new Array(10), "b": new Array(10) }; @@ -278,6 +355,6 @@ class GrandRules extends ChessRules return pieces["b"].join("") + "/pppppppppp/10/10/10/10/10/10/PPPPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 1111 w"; + " w 1111 -"; } } diff --git a/public/javascripts/variants/Loser.js b/public/javascripts/variants/Loser.js index 2d60d6e8..5f156129 100644 --- a/public/javascripts/variants/Loser.js +++ b/public/javascripts/variants/Loser.js @@ -1,20 +1,15 @@ class LoserRules extends ChessRules { - initVariables(fen) - { - const epSq = this.moves.length > 0 ? this.getEpSquare(this.lastMove) : undefined; - this.epSquares = [ epSq ]; - } - - static IsGoodFlags(flags) - { - return true; //anything is good: no flags - } + static get HasFlags() { return false; } - setFlags(fenflags) + setOtherVariables(fen) { - // No castling, hence no flags; but flags defined for compatibility - this.castleFlags = { "w":[false,false], "b":[false,false] }; + const parsedFen = V.ParseFen(fen); + const epSq = parsedFen.enpassant != "-" + ? V.SquareToCoords(parsedFen.enpassant) + : undefined; + this.epSquares = [ epSq ]; + this.scanKingsRooks(fen); } getPotentialPawnMoves([x,y]) @@ -48,6 +43,7 @@ class LoserRules extends ChessRules getPotentialKingMoves(sq) { + // No castle: return this.getSlideNJumpMoves(sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep"); } @@ -111,22 +107,19 @@ class LoserRules extends ChessRules return []; } - // Unused: + // No variables update because no castling updateVariables(move) { } unupdateVariables(move) { } - getFlagsFen() - { - return "-"; - } - checkGameEnd() { // No valid move: you win! return this.turn == "w" ? "1-0" : "0-1"; } - static get VALUES() { //experimental... + static get VALUES() + { + // Experimental... return { 'p': 1, 'r': 7, @@ -197,6 +190,6 @@ class LoserRules extends ChessRules return pieces["b"].join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 0000 w"; //add flags (TODO?!) + " w -"; //no en-passant } } diff --git a/public/javascripts/variants/Magnetic.js b/public/javascripts/variants/Magnetic.js index 2e90e6c0..225489ec 100644 --- a/public/javascripts/variants/Magnetic.js +++ b/public/javascripts/variants/Magnetic.js @@ -1,8 +1,13 @@ class MagneticRules extends ChessRules { - getEpSquare(move) + static get HasEnpassant { return false; } + + setOtherVariables(fen) { - return undefined; //no en-passant + // No en-passant: + const parsedFen = V.ParseFen(fen); + this.setFlags(fenParsed.flags); + this.scanKingsRooks(fen); } getPotentialMovesFrom([x,y]) @@ -19,6 +24,67 @@ class MagneticRules extends ChessRules return moves; } + getPotentialPawnMoves([x,y]) + { + const color = this.turn; + let moves = []; + const [sizeX,sizeY] = [V.size.x,V.size.y]; + const shift = (color == "w" ? -1 : 1); + const firstRank = (color == 'w' ? sizeX-1 : 0); + const startRank = (color == "w" ? sizeX-2 : 1); + const lastRank = (color == "w" ? 0 : sizeX-1); + + if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank) + { + // Normal moves + if (this.board[x+shift][y] == V.EMPTY) + { + moves.push(this.getBasicMove([x,y], [x+shift,y])); + // Next condition because variants with pawns on 1st rank allow them to jump + if ([startRank,firstRank].includes(x) && this.board[x+2*shift][y] == V.EMPTY) + { + // Two squares jump + moves.push(this.getBasicMove([x,y], [x+2*shift,y])); + } + } + // Captures + if (y>0 && this.board[x+shift][y-1] != V.EMPTY + && this.canTake([x,y], [x+shift,y-1])) + { + moves.push(this.getBasicMove([x,y], [x+shift,y-1])); + } + if (y { + // Normal move + if (this.board[x+shift][y] == V.EMPTY) + moves.push(this.getBasicMove([x,y], [x+shift,y], {c:pawnColor,p:p})); + // Captures + if (y>0 && this.board[x+shift][y-1] != V.EMPTY + && this.canTake([x,y], [x+shift,y-1])) + { + moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:pawnColor,p:p})); + } + if (y { + res += V.CoordsToSquare(sq) + ","; + }); + return res.slice(0,-1); //remove last comma + } + // En-passant after 2-sq or 3-sq jumps - getEpSquare(move) + getEpSquare(moveOrSquare) { + if (!moveOrSquare) + return undefined; + if (typeof moveOrSquare === "string") + { + const square = moveOrSquare; + if (square == "-") + return undefined; + let res = []; + square.split(",").forEach(sq => { + res.push(V.SquareToCoords(sq)); + }); + return res; + } + // Argument is a move: + const move = moveOrSquare; const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x]; if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) >= 2) { @@ -248,6 +278,6 @@ class WildebeestRules extends ChessRules return pieces["b"].join("") + "/ppppppppppp/11/11/11/11/11/11/PPPPPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 1111 w"; + " w 1111 -"; } } diff --git a/public/javascripts/variants/Zen.js b/public/javascripts/variants/Zen.js index 64587d20..da4dd7af 100644 --- a/public/javascripts/variants/Zen.js +++ b/public/javascripts/variants/Zen.js @@ -1,10 +1,7 @@ class ZenRules extends ChessRules { // NOTE: enPassant, if enabled, would need to redefine carefully getEpSquare - getEpSquare(move) - { - return undefined; - } + static get HasEnpassant { return false; } // TODO(?): some duplicated code in 2 next functions getSlideNJumpMoves([x,y], steps, oneStep) @@ -184,12 +181,10 @@ class ZenRules extends ChessRules } // Translate initial square (because pieces may fly unusually in this variant!) - const initialSquare = - String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x); + const initialSquare = V.CoordsToSquare(move.start); // Translate final square - const finalSquare = - String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x); + const finalSquare = V.CoordsToSquare(move.end); let notation = ""; const piece = this.getPiece(move.start.x, move.start.y); @@ -218,7 +213,9 @@ class ZenRules extends ChessRules return notation; } - static get VALUES() { //TODO: experimental + static get VALUES() + { + // TODO: experimental return { 'p': 1, 'r': 3,