X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FRecycle.js;h=de0ff5017b9cef5fa255a77ab757d29b1792e532;hb=4313762da3237b04f204e121a20cab3ba7bb5dd2;hp=73d9166989a394f00746298d766d66e0ba139c98;hpb=e727fe31742dfb3e40eb222c94f4199e2be98453;p=vchess.git diff --git a/client/src/variants/Recycle.js b/client/src/variants/Recycle.js index 73d91669..de0ff501 100644 --- a/client/src/variants/Recycle.js +++ b/client/src/variants/Recycle.js @@ -1,7 +1,16 @@ import { ChessRules, PiPo, Move } from "@/base_rules"; import { ArrayFun } from "@/utils/array"; -export const VariantRules = class RecycleRules extends ChessRules { +export class RecycleRules extends ChessRules { + + static get PawnSpecs() { + return Object.assign( + {}, + ChessRules.PawnSpecs, + { promotions: [V.PAWN] } //in fact, none + ); + } + static IsGoodFen(fen) { if (!ChessRules.IsGoodFen(fen)) return false; const fenParsed = V.ParseFen(fen); @@ -13,36 +22,22 @@ export const VariantRules = class RecycleRules extends ChessRules { static ParseFen(fen) { const fenParts = fen.split(" "); - return Object.assign(ChessRules.ParseFen(fen), { - reserve: fenParts[5], - }); - } - - getEpSquare(moveOrSquare) { - if (typeof moveOrSquare !== "object" || move.vanish.length > 0) - return super.getEpSquare(moveOrSquare); - // Landing move: no en-passant - return undefined; + return Object.assign( + ChessRules.ParseFen(fen), + { reserve: fenParts[5] } + ); } - static GenRandInitFen(randomness) { - return ChessRules.GenRandInitFen(randomness) + " 0000000000"; + static GenRandInitFen(options) { + return ChessRules.GenRandInitFen(options) + " 0000000000"; } getFen() { - return ( - super.getFen() + " " + this.getReserveFen() - ); + return super.getFen() + " " + this.getReserveFen(); } getFenForRepeat() { - return ( - this.getBaseFen() + "_" + - this.getTurnFen() + "_" + - this.getFlagsFen() + "_" + - this.getEnpassantFen() + "_" + - this.getReserveFen() - ); + return super.getFenForRepeat() + "_" + this.getReserveFen(); } getReserveFen() { @@ -60,22 +55,23 @@ export const VariantRules = 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] } }; } @@ -90,6 +86,14 @@ export const VariantRules = class RecycleRules extends ChessRules { return this.board[i][j].charAt(1); } + getPPpath(m) { + if (m.vanish.length == 2 && m.appear.length == 2) { + // Castle: show castle symbol + return "Coregal/castle"; + } + return super.getPPpath(m); + } + // Used by the interface: getReservePpath(index, color) { return color + V.RESERVE_PIECES[index]; @@ -130,85 +134,32 @@ export const VariantRules = 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]); } getPotentialPawnMoves([x, y]) { + let moves = super.getPotentialPawnMoves([x, y]); + // Remove pawns on 8th rank ("fallen"): const color = this.turn; - let moves = []; - const [sizeX, sizeY] = [V.size.x, V.size.y]; - const shiftX = color == "w" ? -1 : 1; - const startRank = color == "w" ? sizeX - 2 : 1; - const lastRank = color == "w" ? 0 : sizeX - 1; - - // One square forward - if (this.board[x + shiftX][y] == V.EMPTY) { - moves.push( - this.getBasicMove([x, y], [x + shiftX, y]) - ); - // Next condition because pawns on 1st rank can generally jump - if ( - x == startRank && - this.board[x + 2 * shiftX][y] == V.EMPTY - ) { - // Two squares jump - moves.push(this.getBasicMove([x, y], [x + 2 * shiftX, y])); - } - } - // Captures - for (let shiftY of [-1, 1]) { - if ( - y + shiftY >= 0 && - y + shiftY < sizeY && - this.board[x + shiftX][y + shiftY] != V.EMPTY && - this.canTake([x, y], [x + shiftX, y + shiftY]) - ) { - moves.push( - this.getBasicMove([x, y], [x + shiftX, y + shiftY]) - ); - } - } - - // En passant - const Lep = this.epSquares.length; - const epSquare = this.epSquares[Lep - 1]; //always at least one element - if ( - !!epSquare && - epSquare.x == x + shiftX && - Math.abs(epSquare.y - y) == 1 - ) { - let enpassantMove = this.getBasicMove([x, y], [epSquare.x, epSquare.y]); - enpassantMove.vanish.push({ - x: x, - y: epSquare.y, - p: "p", - c: this.getColor(x, epSquare.y) - }); - moves.push(enpassantMove); - } - - // Post-processing: remove falling pawns - if (x + shiftX == lastRank) { - moves.forEach(m => { - m.appear.pop(); - }); - } - + const lastRank = (color == "w" ? 0 : V.size.x - 1); + moves.forEach(m => { + if (m.appear[0].x == lastRank) m.appear.pop(); + }); return moves; } getAllValidMoves() { - let moves = super.getAllValidMoves(); + let moves = super.getAllPotentialMoves(); const color = this.turn; - for (let i = 0; i < V.RESERVE_PIECES.length; i++) + for (let i = 0; i < V.RESERVE_PIECES.length; i++) { moves = moves.concat( this.getReserveMoves([V.size.x + (color == "w" ? 0 : 1), i]) ); + } return this.filterValid(moves); } @@ -231,31 +182,24 @@ export const VariantRules = class RecycleRules extends ChessRules { return this.getPiece(x2, y2) != V.KING; } - updateVariables(move) { - super.updateVariables(move); - if (move.vanish.length == 2 && move.appear.length == 2) return; //skip castle - const color = V.GetOppCol(this.turn); - if (move.vanish.length == 0) { - this.reserve[color][move.appear[0].p]--; - return; - } - else if (move.vanish.length == 2 && move.vanish[1].c == color) { + 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]++; - } } - unupdateVariables(move) { - super.unupdateVariables(move); + postUndo(move) { + super.postUndo(move); 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]++; - return; - } - else if (move.vanish.length == 2 && move.vanish[1].c == color) { + 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]--; - } } static get SEARCH_DEPTH() { @@ -292,4 +236,5 @@ export const VariantRules = class RecycleRules extends ChessRules { move.appear[0].p != V.PAWN ? move.appear[0].p.toUpperCase() : ""; return piece + "@" + V.CoordsToSquare(move.end); } + };