X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FKoopa.js;h=a624eebbd7a33341bc4d796ea5ff9e92d7838570;hb=7e8a7ea1cb66adb4a987badfb0a3c2f99a21bd0a;hp=f24e5b2f995f74855bb2471074dcd7a1fdbfade9;hpb=6e0f28425075e6d2d79cab6d30bca6ce6d55f19d;p=vchess.git diff --git a/client/src/variants/Koopa.js b/client/src/variants/Koopa.js index f24e5b2f..a624eebb 100644 --- a/client/src/variants/Koopa.js +++ b/client/src/variants/Koopa.js @@ -1,6 +1,7 @@ import { ChessRules, PiPo } from "@/base_rules"; export class KoopaRules extends ChessRules { + static get HasEnpassant() { return false; } @@ -49,18 +50,15 @@ export class KoopaRules extends ChessRules { } getStunnedFen() { - return ( - Object.keys(this.stunned) - .map(square => square + this.stunned[square]) - .join(",") - ); + const squares = Object.keys(this.stunned); + if (squares.length == 0) return "-"; + return squares.map(square => square + this.stunned[square]).join(","); } // Base GenRandInitFen() is fine because en-passant indicator will // stand for stunned indicator. scanKings(fen) { - this.INIT_COL_KING = { w: -1, b: -1 }; // Squares of white and black king: this.kingPos = { w: [-1, -1], b: [-1, -1] }; const fenRows = V.ParseFen(fen).position.split("/"); @@ -72,15 +70,13 @@ export class KoopaRules extends ChessRules { case "k": case "l": this.kingPos["b"] = [i, k]; - this.INIT_COL_KING["b"] = k; break; case "K": case "L": this.kingPos["w"] = [i, k]; - this.INIT_COL_KING["w"] = k; break; default: { - const num = parseInt(fenRows[i].charAt(j)); + const num = parseInt(fenRows[i].charAt(j), 10); if (!isNaN(num)) k += num - 1; } } @@ -100,7 +96,7 @@ export class KoopaRules extends ChessRules { .map(s => { return { square: s.substr(0, 2), - state: parseInt(s[2]) + state: parseInt(s[2], 10) }; }); } @@ -120,7 +116,17 @@ export class KoopaRules extends ChessRules { } getPotentialMovesFrom([x, y]) { - let moves = super.getPotentialMovesFrom([x, y]); + let moves = super.getPotentialMovesFrom([x, y]).filter(m => { + if ( + m.vanish[0].p != V.PAWN || + m.appear[0].p == V.PAWN || + m.vanish.length == 1 + ) { + return true; + } + // Pawn promotion, "capturing": remove duplicates + return m.appear[0].p == V.QUEEN; + }); // Complete moves: stuns & kicks let promoteAfterStun = []; const color = this.turn; @@ -186,7 +192,10 @@ export class KoopaRules extends ChessRules { m.appear[0].x = i; m.appear[0].y = j; // Is it a pawn on last rank? - if ((color == 'w' && i == 0) || (color == 'b' && i == 7)) { + if ( + m.appear[0].p == V.PAWN && + ((color == 'w' && i == 0) || (color == 'b' && i == 7)) + ) { m.appear[0].p = V.ROOK; for (let ppiece of [V.KNIGHT, V.BISHOP, V.QUEEN]) { let mp = JSON.parse(JSON.stringify(m)); @@ -204,18 +213,28 @@ export class KoopaRules extends ChessRules { return moves.concat(promoteAfterStun); } + getPotentialKingMoves(sq) { + return ( + this.getSlideNJumpMoves( + sq, + V.steps[V.ROOK].concat(V.steps[V.BISHOP]), + "oneStep" + ).concat(super.getCastleMoves(sq, null, true, ['r'])) + ); + } + filterValid(moves) { // Forbid kicking own king out const color = this.turn; return moves.filter(m => { - const kingAppear = m.appear.some(a => a.c == color && a.p == V.KING); - return m.vanish.every(v => { - return ( - v.c != color || - !["k", "l"].includes(v.p) || - (v.p == "k" && kingAppear) - ); - }); + const kingVanish = + m.vanish.some(v => v.c == color && ['k', 'l'].includes(v.p)); + if (kingVanish) { + const kingAppear = + m.appear.some(a => a.c == color && ['k', 'l'].includes(a.p)); + return kingAppear; + } + return true; }); } @@ -234,10 +253,16 @@ export class KoopaRules extends ChessRules { // Base method is fine because a stunned king (which won't be detected) // can still castle after going back to normal. super.postPlay(move); - const kIdx = move.vanish.findIndex(v => v.p == "l"); - if (kIdx >= 0) - // A stunned king vanish (game over) - this.kingPos[move.vanish[kIdx].c] = [-1, -1]; + const color = this.turn; + const kp = this.kingPos[color]; + if ( + this.board[kp[0], kp[1]] == V.EMPTY || + !['k', 'l'].includes(this.getPiece(kp[0], kp[1])) || + this.getColor(kp[0], kp[1]) != color + ) { + // King didn't move by itself, and vanished => game over + this.kingPos[color] = [-1, -1]; + } move.stunned = JSON.stringify(this.stunned); // Array of stunned stage 1 pieces (just back to normal then) Object.keys(this.stunned).forEach(square => { @@ -267,11 +292,12 @@ export class KoopaRules extends ChessRules { postUndo(move) { super.postUndo(move); - const kIdx = move.vanish.findIndex(v => v.p == "l"); - if (kIdx >= 0) { - // A stunned king vanished - this.kingPos[move.vanish[kIdx].c] = - [move.vanish[kIdx].x, move.vanish[kIdx].y]; + const oppCol = V.GetOppCol(this.turn); + if (this.kingPos[oppCol][0] < 0) { + // Opponent's king vanished + const psq = + move.vanish.find((v,i) => i >= 1 && ['k', 'l'].includes(v.p)); + this.kingPos[oppCol] = [psq.x, psq.y]; } this.stunned = JSON.parse(move.stunned); for (let i=0; i<8; i++) { @@ -341,4 +367,5 @@ export class KoopaRules extends ChessRules { } return notation; } + };