X-Git-Url: https://git.auder.net/pieces/Cwda/n_black_bishop.svg?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FPacosako.js;h=ae4fe6ff2bded02455b68b4d03aeb0e9bf301fd6;hb=6cc34165a3ca6dcad86030c96df8c0f49c1fabad;hp=5eb96b66b0328681e36032e1929c8e9ffaa80f2b;hpb=059f0aa261609b7421f8576a53d93a764049da5f;p=vchess.git diff --git a/client/src/variants/Pacosako.js b/client/src/variants/Pacosako.js index 5eb96b66..ae4fe6ff 100644 --- a/client/src/variants/Pacosako.js +++ b/client/src/variants/Pacosako.js @@ -34,6 +34,11 @@ export class PacosakoRules extends ChessRules { }; } + static fen2board(f) { + // Underscore is character 95, in file w_ + return f.charCodeAt() <= 95 ? "w" + f.toLowerCase() : "b" + f; + } + static IsGoodPosition(position) { if (position.length == 0) return false; const rows = position.split("/"); @@ -508,6 +513,8 @@ export class PacosakoRules extends ChessRules { castlingCheck: for (let castleSide = 0; castleSide < 2; castleSide++) { if (this.castleFlags[c][castleSide] >= 8) continue; const rookPos = this.castleFlags[c][castleSide]; + const castlingColor = this.board[x][rookPos].charAt(0); + const castlingPiece = this.board[x][rookPos].charAt(1); // Nothing on the path of the king ? const finDist = finalSquares[castleSide][0] - y; @@ -561,14 +568,14 @@ export class PacosakoRules extends ChessRules { new PiPo({ x: x, y: finalSquares[castleSide][1], - p: V.ROOK, - c: c + p: castlingPiece, + c: castlingColor }) ], vanish: [ // King might be initially disguised (Titan...) new PiPo({ x: x, y: y, p: V.KING, c: c }), - new PiPo({ x: x, y: rookPos, p: V.ROOK, c: c }) + new PiPo({ x: x, y: rookPos, p: castlingPiece, c: castlingColor }) ], end: Math.abs(y - rookPos) <= 2 @@ -581,6 +588,14 @@ export class PacosakoRules extends ChessRules { return moves; } + getEnpassantCaptures(sq, shiftX) { + // HACK: when artificially change turn, do not consider en-passant + const mcMod2 = this.movesCount % 2; + const c = this.turn; + if ((c == 'w' && mcMod2 == 1) || (c == 'b' && mcMod2 == 0)) return []; + return super.getEnpassantCaptures(sq, shiftX); + } + isAttacked_aux(files, color, positions, fromSquare, released) { // "positions" = array of FENs to detect infinite loops. Example: // r1q1k2r/p1Pb1ppp/5n2/1f1p4/AV5P/P1eDP3/3B1PP1/R3K1NR, @@ -661,8 +676,47 @@ export class PacosakoRules extends ChessRules { return moves.filter(m => !this.oppositeMoves(this.umoves[L - 1], m)); } + updateCastleFlags(move, piece) { + const c = this.turn; + const firstRank = (c == "w" ? 7 : 0); + if (piece == V.KING && move.appear.length > 0) + this.castleFlags[c] = [V.size.y, V.size.y]; + else if ( + move.start.x == firstRank && + this.castleFlags[c].includes(move.start.y) + ) { + const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1); + this.castleFlags[c][flagIdx] = V.size.y; + } + else if ( + move.end.x == firstRank && + this.castleFlags[c].includes(move.end.y) + ) { + // Move to our rook: necessary normal piece, to union, releasing + // (or the rook was moved before!) + const flagIdx = (move.end.y == this.castleFlags[c][0] ? 0 : 1); + this.castleFlags[c][flagIdx] = V.size.y; + } + } + + prePlay(move) { + // Easier before move is played in this case (flags are saved) + const c = this.turn; + const L = this.lastMoveEnd.length; + const lm = this.lastMoveEnd[L-1]; + const piece = (!!lm ? lm.p : move.vanish[0].p); + if (piece == V.KING) + this.kingPos[c] = [move.appear[0].x, move.appear[0].y]; + this.updateCastleFlags(move, piece); + const pawnFirstRank = (c == 'w' ? 6 : 1); + if (move.start.x == pawnFirstRank) + // This move (potentially) turns off a 2-squares pawn flag + this.pawnFlags[c][move.start.y] = false; + } + play(move) { move.flags = JSON.stringify(this.aggregateFlags()); + this.prePlay(move); this.epSquares.push(this.getEpSquare(move)); // Check if the move is the last of the turn: all cases except releases if (!move.released) { @@ -674,34 +728,6 @@ export class PacosakoRules extends ChessRules { else this.lastMoveEnd.push(Object.assign({ p: move.released }, move.end)); V.PlayOnBoard(this.board, move); this.umoves.push(this.getUmove(move)); - this.postPlay(move); - } - - postPlay(move) { - if (move.vanish.length == 0) - // A released piece just moved. Cannot be the king. - return; - const c = move.vanish[0].c; - const piece = move.vanish[0].p; - if (piece == V.KING) - this.kingPos[c] = [move.appear[0].x, move.appear[0].y]; - this.updateCastleFlags(move, piece); - if ( - [1, 6].includes(move.start.x) && - move.vanish.length >= 1 && - move.appear.length == 1 - ) { - // Does this move turn off a 2-squares pawn flag? - if ( - move.vanish[0].p == V.PAWN || - ( - !(ChessRules.PIECES.includes(move.vanish[0].p)) && - this.getUnionPieces(move.vanish[0].c, move.vanish[0].p)[c] == V.PAWN - ) - ) { - this.pawnFlags[move.start.x == 6 ? "w" : "b"][move.start.y] = false; - } - } } undo(move) {