X-Git-Url: https://git.auder.net/?p=vchess.git;a=blobdiff_plain;f=public%2Fjavascripts%2Fvariants%2FCrazyhouse.js;h=3d9c743f8dc23bf510ccc4963b184951f8e3c81b;hp=37337650c7bb94bf506cfd5fe8fab251eef8677f;hb=b6487fb9c41705187cf97215fc9e8f86a59057c7;hpb=6752407b88b6d7678b9b19df4ffe1224d17625d7 diff --git a/public/javascripts/variants/Crazyhouse.js b/public/javascripts/variants/Crazyhouse.js index 37337650..3d9c743f 100644 --- a/public/javascripts/variants/Crazyhouse.js +++ b/public/javascripts/variants/Crazyhouse.js @@ -1,76 +1,153 @@ class CrazyhouseRules extends ChessRules { - initVariables(fen) + static IsGoodFen(fen) { - super.initVariables(fen); - // Also init reserves (used by the interface to show landing pieces) - const V = VariantRules; + 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; + if (fenParsed.promoted == "-") + return true; //no promoted piece on board + const squares = fenParsed.promoted.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 ParseFen(fen) + { + const fenParts = fen.split(" "); + return Object.assign( + ChessRules.ParseFen(fen), + { + reserve: fenParts[5], + promoted: fenParts[6], + } + ); + } + + static GenRandInitFen() + { + return ChessRules.GenRandInitFen() + " 0000000000 -"; + } + + getFen() + { + return super.getFen() + " " + this.getReserveFen() + " " + this.getPromotedFen(); + } + + getReserveFen() + { + let counts = new Array(10); + for (let i=0; i 0) + res = res.slice(0,-1); //remove last comma + else + res = "-"; + 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]), } }; - const [sizeX,sizeY] = VariantRules.size; - this.promoted = doubleArray(sizeX, sizeY, false); - // May be a continuation: adjust numbers of pieces in reserve + promoted pieces - this.moves.forEach(m => { this.updateVariables(m); }); + this.promoted = doubleArray(V.size.x, V.size.y, false); + if (fenParsed.promoted != "-") + { + for (let square of fenParsed.promoted.split(",")) + { + const [x,y] = V.SquareToCoords(square); + promoted[x][y] = true; + } + } } getColor(i,j) { - const sizeX = VariantRules.size[0]; - if (i >= sizeX) - return (i==sizeX ? "w" : "b"); + if (i >= V.size.x) + return (i==V.size.x ? "w" : "b"); return this.board[i][j].charAt(0); } + getPiece(i,j) { - const sizeX = VariantRules.size[0]; - if (i >= sizeX) - return VariantRules.RESERVE_PIECES[j]; + if (i >= V.size.x) + return V.RESERVE_PIECES[j]; return this.board[i][j].charAt(1); } // Used by the interface: getReservePpath(color, index) { - return color + VariantRules.RESERVE_PIECES[index]; + return color + V.RESERVE_PIECES[index]; } - // Put an ordering on reserve pieces - static get RESERVE_PIECES() { - const V = VariantRules; + // Ordering on reserve pieces + static get RESERVE_PIECES() + { return [V.PAWN,V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN]; } getReserveMoves([x,y]) { const color = this.turn; - const p = VariantRules.RESERVE_PIECES[y]; + const p = V.RESERVE_PIECES[y]; if (this.reserve[color][p] == 0) return []; let moves = []; - const [sizeX,sizeY] = VariantRules.size; - const pawnShift = (p==VariantRules.PAWN ? 1 : 0); - for (let i=pawnShift; i= sizeX) + if (x >= V.size.x) { - // Reserves, outside of board: x == sizeX + // Reserves, outside of board: x == sizeX(+1) return this.getReserveMoves([x,y]); } // Standard moves @@ -108,9 +184,8 @@ class CrazyhouseRules extends ChessRules { let moves = super.getAllValidMoves(); const color = this.turn; - const sizeX = VariantRules.size[0]; - for (let i=0; i 0) return true; } @@ -136,82 +212,41 @@ class CrazyhouseRules extends ChessRules super.updateVariables(move); if (move.vanish.length == 2 && move.appear.length == 2) return; //skip castle - const color = this.turn; - const V = VariantRules; - // Three types of move: - // 1. Rebirth: just update material - // 2. Standard move: - // a. check if a promoted piece is moving - // b. check if it's a promotion (mutually exclusive) - // 3. Capture: - // a. check if a promoted piece is captured (and mark move) - // b. check if a promoted piece is moving - // c. check if it's a promotion (mutually exclusive with b) + const color = move.appear[0].c; if (move.vanish.length == 0) - this.reserve[color][move.appear[0].p]--; - else if (move.vanish.length == 1) { - if (this.promoted[move.start.x][move.start.y]) - { - this.promoted[move.start.x][move.start.y] = false; - this.promoted[move.end.x][move.end.y] = true; - } - else if (move.vanish[0].p == V.PAWN && move.appear[0].p != V.PAWN) - this.promoted[move.end.x][move.end.y] = true; - } - else //capture - { - if (this.promoted[move.end.x][move.end.y]) - { - move.capturePromoted = true; //required for undo - this.reserve[color][VariantRules.PAWN]++; - this.promoted[move.end.x][move.end.y] = false; - } - else - this.reserve[color][move.vanish[1].p]++; - if (this.promoted[move.start.x][move.start.y]) - { - this.promoted[move.start.x][move.start.y] = false; - this.promoted[move.end.x][move.end.y] = true; - } - else if (move.vanish[0].p == V.PAWN && move.appear[0].p != V.PAWN) - this.promoted[move.end.x][move.end.y] = true; + this.reserve[color][move.appear[0].p]--; + return; } + move.movePromoted = this.promoted[move.start.x][move.start.y]; + move.capturePromoted = this.promoted[move.end.x][move.end.y] + this.promoted[move.start.x][move.start.y] = false; + this.promoted[move.end.x][move.end.y] = move.movePromoted + || (move.vanish[0].p == V.PAWN && move.appear[0].p != V.PAWN); + if (move.capturePromoted) + this.reserve[color][V.PAWN]++; + else if (move.vanish.length == 2) + this.reserve[color][move.vanish[1].p]++; } unupdateVariables(move) { super.unupdateVariables(move); + if (move.vanish.length == 2 && move.appear.length == 2) + return; const color = this.turn; - const V = VariantRules; if (move.vanish.length == 0) - this.reserve[color][move.appear[0].p]++; - else if (move.vanish.length == 1) { - if (this.promoted[move.end.x][move.end.y]) - { - this.promoted[move.end.x][move.end.y] = false; - if (move.vanish[0].p != V.PAWN || move.appear[0].p == V.PAWN) - { - // Not a promotion (= promoted piece creation) - this.promoted[move.start.x][move.start.y] = true; - } - } - } - else //capture - { - if (this.promoted[move.end.x][move.end.y]) - { - this.promoted[move.end.x][move.end.y] = !!move.capturePromoted; - if (move.vanish[0].p != V.PAWN || move.appear[0].p == V.PAWN) - this.promoted[move.start.x][move.start.y] = true; - } - // Un-update material: - if (move.capturePromoted) - this.reserve[color][VariantRules.PAWN]--; - else - this.reserve[color][move.vanish[1].p]--; + this.reserve[color][move.appear[0].p]++; + return; } + if (move.movePromoted) + this.promoted[move.start.x][move.start.y] = true; + this.promoted[move.end.x][move.end.y] = move.capturePromoted; + if (move.capturePromoted) + this.reserve[color][V.PAWN]--; + else if (move.vanish.length == 2) + this.reserve[color][move.vanish[1].p]--; } static get SEARCH_DEPTH() { return 2; } //high branching factor @@ -220,11 +255,11 @@ class CrazyhouseRules extends ChessRules { let evaluation = super.evalPosition(); // Add reserves: - for (let i=0; i 0) return super.getLongNotation(move); - const finalSquare = - String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x); - return "@" + finalSquare; + return "@" + V.CoordsToSquare(move.end); } } + +const VariantRules = CrazyhouseRules;