X-Git-Url: https://git.auder.net/assets/rpsls.css?a=blobdiff_plain;f=base_rules.js;h=0f89cc429b8c97da44272d3add07813c90df776f;hb=7fbcb53de45ba7b7aed99d6087928779713810b1;hp=47f70c2f1be3c2e7ada38dd81d2bec9e35766d68;hpb=714ce6d8c8981175b3a2bdacdfc707ca5a1ce587;p=xogo.git diff --git a/base_rules.js b/base_rules.js index 47f70c2..0f89cc4 100644 --- a/base_rules.js +++ b/base_rules.js @@ -97,6 +97,14 @@ export default class ChessRules { return true; } + // Allow to take (moving: not disappearing) own pieces? + get hasSelfCaptures() { + return ( + this.options["recycle"] || + (this.options["teleport"] && this.subTurnTeleport == 1) + ); + } + get hasReserve() { return ( !!this.options["crazyhouse"] || @@ -225,7 +233,7 @@ export default class ChessRules { ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'], { randomness: this.options["randomness"], - between: {p1: 'k', p2: 'r'}, + between: [{p1: 'k', p2: 'r'}], diffCol: ['b'], flags: ['r'] } @@ -316,7 +324,7 @@ export default class ChessRules { // Flags part of the FEN string getFlagsFen() { - return ["w", "b"].map(c => { + return ['w', 'b'].map(c => { return this.castleFlags[c].map(x => x.toString(36)).join(""); }).join(""); } @@ -332,7 +340,7 @@ export default class ChessRules { if (o.init) return "000000000000"; return ( - ["w","b"].map(c => Object.values(this.reserve[c]).join("")).join("") + ['w', 'b'].map(c => Object.values(this.reserve[c]).join("")).join("") ); } @@ -408,14 +416,14 @@ export default class ChessRules { } // Some additional variables from FEN (variant dependant) - setOtherVariables(fenParsed) { + setOtherVariables(fenParsed, pieceArray) { // Set flags and enpassant: if (this.hasFlags) this.setFlags(fenParsed.flags); if (this.hasEnpassant) this.epSquare = this.getEpSquare(fenParsed.enpassant); if (this.hasReserve && !this.isDiagram) - this.initReserves(fenParsed.reserve); + this.initReserves(fenParsed.reserve, pieceArray); if (this.options["crazyhouse"]) this.initIspawn(fenParsed.ispawn); if (this.options["teleport"]) { @@ -571,11 +579,18 @@ export default class ChessRules { // Get SVG board (background, no pieces) getSvgChessboard() { - const flipped = this.flippedBoard; let board = ` `; + board += this.getBaseSvgChessboard(); + board += ""; + return board; + } + + getBaseSvgChessboard() { + let board = ""; + const flipped = this.flippedBoard; for (let i=0; i < this.size.x; i++) { for (let j=0; j < this.size.y; j++) { if (!this.onBoard(i, j)) @@ -597,7 +612,6 @@ export default class ChessRules { />`; } } - board += ""; return board; } @@ -634,7 +648,13 @@ export default class ChessRules { else this[arrName] = ArrayFun.init(this.size.x, this.size.y, null); if (arrName == "d_pieces") - this.marks.forEach(([i, j]) => addPiece(i, j, arrName, "mark")); + this.marks.forEach((m) => { + const formattedSquare = + (this.size.x - parseInt(m.substring(1), 10)).toString(36) + + (m.charCodeAt(0) - 97).toString(36); + const mCoords = V.SquareToCoords(formattedSquare); + addPiece(mCoords.x, mCoords.y, arrName, "mark"); + }); }; if (this.marks) conditionalReset("d_pieces"); @@ -1188,7 +1208,7 @@ export default class ChessRules { } pieces(color, x, y) { - const pawnShift = this.getPawnShift(color); + const pawnShift = this.getPawnShift(color || 'w'); return { 'p': { "class": "pawn", @@ -1512,12 +1532,8 @@ export default class ChessRules { let moves = this.getPotentialMovesOf(piece, [x, y]); if (piece == "p" && this.hasEnpassant && this.epSquare) Array.prototype.push.apply(moves, this.getEnpassantCaptures([x, y])); - if ( - this.isKing(0, 0, piece) && this.hasCastle && - this.castleFlags[color || this.turn].some(v => v < this.size.y) - ) { + if (this.isKing(0, 0, piece) && this.hasCastle) Array.prototype.push.apply(moves, this.getCastleMoves([x, y])); - } return this.postProcessPotentialMoves(moves); } @@ -1720,10 +1736,7 @@ export default class ChessRules { }); Array.prototype.push.apply(squares, zenCaptures); } - if ( - this.options["recycle"] || - (this.options["teleport"] && this.subTurnTeleport == 1) - ) { + if (this.hasSelfCaptures) { const selfCaptures = this.findDestSquares( [x, y], { @@ -1791,7 +1804,10 @@ export default class ChessRules { continue outerLoop; const oldIJ = [i, j]; [i, j] = this.increment([i, j], step); - if (Math.abs(j - oldIJ[1]) > 1 || Math.abs(i - oldIJ[0]) > 1) { + if ( + Math.abs(i - oldIJ[0]) != Math.abs(step[0]) || + Math.abs(j - oldIJ[1]) != Math.abs(step[1]) + ) { // Boundary between segments (cylinder or circular mode) segments.push([[segStart[0], segStart[1]], oldIJ]); segStart = [i, j]; @@ -2010,8 +2026,9 @@ export default class ChessRules { return []; } - getCastleMoves([x, y], finalSquares, castleWith) { + getCastleMoves([x, y], finalSquares, castleWith, castleFlags) { const c = this.getColor(x, y); + castleFlags = castleFlags || this.castleFlags[c]; // Castling ? const oppCols = this.getOppCols(c); @@ -2025,12 +2042,12 @@ export default class ChessRules { castleSide < 2; castleSide++ //large, then small ) { - if (this.castleFlags[c][castleSide] >= this.size.y) + if (castleFlags[castleSide] >= this.size.y) continue; // If this code is reached, rook and king are on initial position // NOTE: in some variants this is not a rook - const rookPos = this.castleFlags[c][castleSide]; + const rookPos = castleFlags[castleSide]; const castlingPiece = this.getPiece(x, rookPos); if ( this.board[x][rookPos] == "" || @@ -2233,11 +2250,20 @@ export default class ChessRules { this.board[psq.x][psq.y] = psq.c + psq.p; } - updateCastleFlags(move) { + // NOTE: arg "castleFlags" for Coregal or Twokings + updateCastleFlags(move, castleFlags, king) { + castleFlags = castleFlags || this.castleFlags; + // If flags already off, no need to re-check: + if ( + Object.values(castleFlags).every(cvals => + cvals.every(val => val >= this.size.y)) + ) { + return; + } // Update castling flags if start or arrive from/at rook/king locations move.appear.concat(move.vanish).forEach(psq => { - if (this.isKing(0, 0, psq.p)) - this.castleFlags[psq.c] = [this.size.y, this.size.y]; + if ((king && psq.p == king) || (!king && this.isKing(0, 0, psq.p))) + castleFlags[psq.c] = [this.size.y, this.size.y]; // NOTE: not "else if" because king can capture enemy rook... let c = ""; if (psq.x == 0) @@ -2245,22 +2271,16 @@ export default class ChessRules { else if (psq.x == this.size.x - 1) c = "w"; if (c != "") { - const fidx = this.castleFlags[c].findIndex(f => f == psq.y); + const fidx = castleFlags[c].findIndex(f => f == psq.y); if (fidx >= 0) - this.castleFlags[c][fidx] = this.size.y; + castleFlags[c][fidx] = this.size.y; } }); } prePlay(move) { - if ( - this.hasCastle && - // If flags already off, no need to re-check: - Object.values(this.castleFlags).some(cvals => - cvals.some(val => val < this.size.y)) - ) { + if (this.hasCastle) this.updateCastleFlags(move); - } if (this.options["crazyhouse"]) { move.vanish.forEach(v => { const square = C.CoordsToSquare({x: v.x, y: v.y}); @@ -2327,10 +2347,11 @@ export default class ChessRules { if (this.options["teleport"]) { if ( this.subTurnTeleport == 1 && - move.vanish.length > move.appear.length && + move.vanish.length == 2 && + move.appear.length == 1 && move.vanish[1].c == this.turn ) { - const v = move.vanish[move.vanish.length - 1]; + const v = move.vanish[1]; this.captured = {x: v.x, y: v.y, c: v.c, p: v.p}; this.subTurnTeleport = 2; return;