X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=variants%2FChakart%2Fclass.js;h=815be74b8d1d24f1e2ed711ec01099c754995292;hb=f31de5e46015a93dca20765da61670035ce8f491;hp=24bbd3e86887b0fc93e4b59c7d8cf4515e8eda63;hpb=fc12475fd434835816796ece83d93341af6c1550;p=xogo.git diff --git a/variants/Chakart/class.js b/variants/Chakart/class.js index 24bbd3e..815be74 100644 --- a/variants/Chakart/class.js +++ b/variants/Chakart/class.js @@ -1,7 +1,7 @@ import ChessRules from "/base_rules.js"; import GiveawayRules from "/variants/Giveaway/class.js"; -import { ArrayFun } from "/utils/array.js"; -import { Random } from "/utils/alea.js"; +import {ArrayFun} from "/utils/array.js"; +import {Random} from "/utils/alea.js"; import PiPo from "/utils/PiPo.js"; import Move from "/utils/Move.js"; @@ -127,18 +127,16 @@ export default class ChakartRules extends ChessRules { ] } }, - specials, bowsered, super.pieces(color, x, y)); + specials, bowsered, super.pieces(color, x, y) + ); } - genRandInitFen(seed) { + genRandInitBaseFen() { const options = Object.assign({mode: "suicide"}, this.options); const gr = new GiveawayRules({options: options, genFenOnly: true}); - const baseFen = gr.genRandInitFen(seed); - const fenParts = baseFen.split(" "); - let others = JSON.parse(fenParts[3]); - delete others["enpassant"]; - others["flags"] = "1111"; //Peach + Mario flags - return fenParts.slice(0, 3).join(" ") + " " + JSON.stringify(others); + let res = gr.genRandInitBaseFen(); + res.o["flags"] = "1111"; //Peach + Mario flags + return res; } fen2board(f) { @@ -178,40 +176,35 @@ export default class ChakartRules extends ChessRules { } setOtherVariables(fenParsed) { - this.setFlags(fenParsed.flags); - this.reserve = {}; //to be filled later + super.setOtherVariables(fenParsed); this.egg = null; - this.moveStack = []; // Change seed (after FEN generation!!) // so that further calls differ between players: Random.setSeed(Math.floor(19840 * Math.random())); } + initReserves() { + this.reserve = {}; //to be filled later + } + + canStepOver(i, j) { + return ( + this.board[i][j] == "" || + ['i', V.EGG, V.MUSHROOM].includes(this.getPiece(i, j)) + ); + } + // For Toadette bonus - getDropMovesFrom([c, p]) { - if (typeof c != "string" || this.reserve[c][p] == 0) - return []; - let moves = []; - const start = (c == 'w' && p == 'p' ? 1 : 0); - const end = (c == 'b' && p == 'p' ? 7 : 8); - for (let i = start; i < end; i++) { - for (let j = 0; j < this.size.y; j++) { - const pieceIJ = this.getPiece(i, j); - const colIJ = this.getColor(i, j); - if (this.board[i][j] == "" || colIJ == 'a' || pieceIJ == 'i') { - let m = new Move({ - start: {x: c, y: p}, - appear: [new PiPo({x: i, y: j, c: c, p: p})], - vanish: [] - }); - // A drop move may remove a bonus (or hidden queen!) - if (this.board[i][j] != "") - m.vanish.push(new PiPo({x: i, y: j, c: colIJ, p: pieceIJ})); - moves.push(m); - } - } - } - return moves; + canDrop([c, p], [i, j]) { + return ( + ( + this.board[i][j] == "" || + this.getColor(i, j) == 'a' || + this.getPiece(i, j) == 'i' + ) + && + (p != "p" || (c == 'w' && i < this.size.x - 1) || (c == 'b' && i > 0)) + ); } getPotentialMovesFrom([x, y]) { @@ -274,20 +267,13 @@ export default class ChakartRules extends ChessRules { case 'b': case 'r': // Explicitely listing types to avoid moving immobilized piece - moves = this.getPotentialMovesOf(piece, [x, y]); + moves = super.getPotentialMovesOf(piece, [x, y]); break; } } return moves; } - canStepOver(i, j) { - return ( - this.board[i][j] == "" || - ['i', V.EGG, V.MUSHROOM].includes(this.getPiece(i, j)) - ); - } - getPawnMovesFrom([x, y]) { const color = this.turn; const oppCol = C.GetOppCol(color); @@ -353,14 +339,14 @@ export default class ChakartRules extends ChessRules { getKnightMovesFrom([x, y]) { // Add egg on initial square: - return this.getPotentialMovesOf('n', [x, y]).map(m => { + return super.getPotentialMovesOf('n', [x, y]).map(m => { m.appear.push(new PiPo({p: "e", c: "a", x: x, y: y})); return m; }); } getQueenMovesFrom(sq) { - const normalMoves = this.getPotentialMovesOf('q', sq); + const normalMoves = super.getPotentialMovesOf('q', sq); // If flag allows it, add 'invisible movements' let invisibleMoves = []; if (this.powerFlags[this.turn]['q']) { @@ -382,10 +368,10 @@ export default class ChakartRules extends ChessRules { } getKingMovesFrom([x, y]) { - let moves = this.getPotentialMovesOf('k', [x, y]); + let moves = super.getPotentialMovesOf('k', [x, y]); // If flag allows it, add 'remote shell captures' if (this.powerFlags[this.turn]['k']) { - let shellCaptures = this.getPotentialMovesOf('y', [x, y]); + let shellCaptures = super.getPotentialMovesOf('y', [x, y]); shellCaptures.forEach(sc => { sc.shell = true; //easier play() sc.choice = 'z'; //to display in showChoices() @@ -415,57 +401,11 @@ export default class ChakartRules extends ChessRules { super.showChoices(moves); return false; } - if (!move.nextComputed) { - // Set potential random effects, so that play() is deterministic - // from opponent viewpoint: - const endPiece = this.getPiece(move.end.x, move.end.y); - switch (endPiece) { - case V.EGG: - move.egg = Random.sample(V.EGG_SURPRISE); - move.next = this.getEggEffect(move); - break; - case V.MUSHROOM: - move.next = this.getMushroomEffect(move); - break; - case V.BANANA: - case V.BOMB: - move.next = this.getBombBananaEffect(move, endPiece); - break; - } - if (!move.next && move.appear.length > 0 && !move.kingboo) { - const movingPiece = move.appear[0].p; - if (['b', 'r'].includes(movingPiece)) { - // Drop a banana or bomb: - const bs = - this.getRandomSquare([move.end.x, move.end.y], - movingPiece == 'r' - ? [[1, 1], [1, -1], [-1, 1], [-1, -1]] - : [[1, 0], [-1, 0], [0, 1], [0, -1]], - "freeSquare"); - if (bs) { - move.appear.push( - new PiPo({ - x: bs[0], - y: bs[1], - c: 'a', - p: movingPiece == 'r' ? 'd' : 'w' - }) - ); - if (this.board[bs[0]][bs[1]] != "") { - move.vanish.push( - new PiPo({ - x: bs[0], - y: bs[1], - c: this.getColor(bs[0], bs[1]), - p: this.getPiece(bs[0], bs[1]) - }) - ); - } - } - } - } - move.nextComputed = true; - } + this.postPlay(move, color, oppCol); + return true; + } + + postPlay(move, color, oppCol) { this.egg = move.egg; if (move.egg == "toadette") { this.reserve = { w: {}, b: {} }; @@ -516,7 +456,11 @@ export default class ChakartRules extends ChessRules { this.getColor(i, j) == oppCol ) { const pieceIJ = this.getPiece(i, j); - if (pieceIJ == 'i') { + if ( + pieceIJ == 'i' && + // Ensure that current move doesn't erase invisible queen + move.appear.every(a => a.x != i || a.y != j) + ) { move.vanish.push(new PiPo({x: i, y: j, c: oppCol, p: 'i'})); move.appear.push(new PiPo({x: i, y: j, c: oppCol, p: 'q'})); } @@ -526,15 +470,73 @@ export default class ChakartRules extends ChessRules { } } } - if (!move.next && !["daisy", "toadette", "kingboo"].includes(move.egg)) { - this.turn = oppCol; - this.movesCount++; - } + this.playOnBoard(move); + super.postPlay(move); + } + + playVisual(move, r) { + super.playVisual(move, r); if (move.egg) this.displayBonus(move); - this.playOnBoard(move); - this.nextMove = move.next; - return true; + } + + computeNextMove(move) { + // Set potential random effects, so that play() is deterministic + // from opponent viewpoint: + const endPiece = this.getPiece(move.end.x, move.end.y); + switch (endPiece) { + case V.EGG: + move.egg = Random.sample(V.EGG_SURPRISE); + move.next = this.getEggEffect(move); + break; + case V.MUSHROOM: + move.next = this.getMushroomEffect(move); + break; + case V.BANANA: + case V.BOMB: + move.next = this.getBombBananaEffect(move, endPiece); + break; + } + // NOTE: Chakart has also some side-effects: + if ( + !move.next && move.appear.length > 0 && + !move.kingboo && !move.luigiEffect + ) { + const movingPiece = move.appear[0].p; + if (['b', 'r'].includes(movingPiece)) { + // Drop a banana or bomb: + const bs = + this.getRandomSquare([move.end.x, move.end.y], + movingPiece == 'r' + ? [[1, 1], [1, -1], [-1, 1], [-1, -1]] + : [[1, 0], [-1, 0], [0, 1], [0, -1]], + "freeSquare"); + if (bs) { + move.appear.push( + new PiPo({ + x: bs[0], + y: bs[1], + c: 'a', + p: movingPiece == 'r' ? 'd' : 'w' + }) + ); + if (this.board[bs[0]][bs[1]] != "") { + move.vanish.push( + new PiPo({ + x: bs[0], + y: bs[1], + c: this.getColor(bs[0], bs[1]), + p: this.getPiece(bs[0], bs[1]) + }) + ); + } + } + } + } + } + + isLastMove(move) { + return !move.next && !["daisy", "toadette", "kingboo"].includes(move.egg); } // Helper to set and apply banana/bomb effect @@ -584,6 +586,7 @@ export default class ChakartRules extends ChessRules { new PiPo({x: coords[0], y: coords[1], c: oldColor, p: piece}) ] }); + em.luigiEffect = true; //avoid dropping bomb/banana by mistake } break; case "bowser": @@ -703,23 +706,13 @@ export default class ChakartRules extends ChessRules { return moves; } - playPlusVisual(move, r) { - const nextLines = () => { - if (!this.play(move)) - return; - this.moveStack.push(move); - this.playVisual(move, r); - if (this.nextMove) - this.playPlusVisual(this.nextMove, r); - else { - this.afterPlay(this.moveStack); - this.moveStack = []; - } - }; - if (this.moveStack.length == 0) - nextLines(); - else - this.animate(move, nextLines); + // Kingboo bonus can be animated better: + customAnimate(move, segments, cb) { + if (!move.kingboo) + return 0; + super.animateMoving(move.end, move.start, null, + segments.reverse().map(s => s.reverse()), cb); + return 1; } };