X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=variants%2FBario%2Fclass.js;fp=variants%2FBario%2Fclass.js;h=80a3cce3e13472707d5db80ce2d9e744c8763ddb;hb=dc10e429231932c19da6d1ff2ce98c7a042829ab;hp=0000000000000000000000000000000000000000;hpb=d6d0a46e5c8c1d9176f4a9e9c44a4b5f2ed791e7;p=xogo.git diff --git a/variants/Bario/class.js b/variants/Bario/class.js new file mode 100644 index 0000000..80a3cce --- /dev/null +++ b/variants/Bario/class.js @@ -0,0 +1,238 @@ +import ChessRules from "/base_rules.js"; +import PiPo from "/utils/PiPo.js"; +import Move from "/utils/Move.js"; + +export default class BarioRules extends ChessRules { + + static get Options() { + return { + // TODO: Zen too? + styles: [ + "atomic", "cannibal", "capture", "cylinder", + "dark", "madrasi", "rifle", "teleport" + ] + }; + } + + // Does not really seem necessary (although the author mention it) + // Instead, first move = pick a square for the king. + get hasFlags() { + return false; + } + get hasReserve() { + return true; + } + + pieces(color, x, y) { + return Object.assign( + { + 'u': { + "class": "undefined", + moves: [] + } + }, + super.pieces(color, x, y) + ); + } + + get onlyClick() { + return this.movesCount <= 1; + } + + // Initiate the game by choosing a square for the king: + doClick(coords) { + const color = this.turn; + if ( + this.movesCount <= 1 && + ( + (color == 'w' && coords.x == this.size.x - 1) || + (color == 'b' && coords.x == 0) + ) + ) { + return new Move({ + appear: [ new PiPo({x: coords.x, y: coords.y, c: color, p: 'k' }) ], + vanish: [ new PiPo({x: coords.x, y: coords.y, c: color, p: 'u' }) ] + }); + } + return null; + } + + genRandInitBaseFen() { + return { + fen: "uuuuuuuu/pppppppp/8/8/8/8/PPPPPPPP/UUUUUUUU", + o: {} + } + } + + getPartFen(o) { + return Object.assign( + { + captureUndef: (o.init || !this.captureUndef) + ? "-" + : C.CoordsToSquare(this.captureUndef) + }, + super.getPartFen(o) + ); + } + + getReserveFen(o) { + if (o.init) + return "22212221"; + return ( + ["w","b"].map(c => Object.values(this.reserve[c]).join("")).join("") + ); + } + + initReserves(reserveStr) { + super.initReserves(reserveStr, ['r', 'n', 'b', 'q']); + } + + setOtherVariables(fenParsed) { + super.setOtherVariables(fenParsed); + this.captureUndef = fenParsed.captureUndef == '-' + ? null : + C.SquareToCoords(fenParsed.captureUndef); + this.definition = null; + } + + canDrop([c, p], [i, j]) { + switch (this.subTurn) { + case 0: + return i == this.captureUndef.x && j == this.captureUndef.y; + case 1: + return this.getPiece(i, j) == 'u' && c == this.getColor(i, j); + } + return false; //never reached + } + + getPotentialMovesFrom([x, y]) { + if (this.movesCount <= 1) + return []; + let moves = []; + switch (this.subTurn) { + case 0: + if (typeof x == "string") + moves = this.getDropMovesFrom([x, y]); + break; + case 1: + // Both normal move (from defined piece) and definition allowed + if (typeof x == "string") + moves = this.getDropMovesFrom([x, y]); + else if (this.getPiece(x, y) != 'u') + moves = super.getPotentialMovesFrom([x, y]); + break; + case 2: + // We can only move the just-defined piece + if (x == this.definition.x && y == this.definition.y) + moves = super.getPotentialMovesFrom([x, y]); + break; + } + return moves; + } + + filterValid(moves) { + if (this.movesCount <= 1 || this.subTurn == 0) + return moves; + if (this.subTurn == 1) { + // Remove defining moves with un-movable def piece + moves = moves.filter(m => { + if (m.vanish.length >= 2 || m.vanish[0].p != 'u') + return true; + this.playOnBoard(m); + const canMove = super.filterValid( + super.getPotentialMovesFrom([m.end.x, m.end.y])).length >= 1; + this.undoOnBoard(m); + return canMove; + }); + } + return super.filterValid(moves); + } + + atLeastOneMove(color) { + if (this.subTurn != 1) + return true; + return super.atLeastOneMove(color); + } + + // TODO: this method fails to detect undefined checks + underCheck(square_s, oppCol) { + if (super.underCheck(square_s, oppCol)) + return true; + // Check potential specializations of undefined using reserve: + const allAttacks = Array.prototype.concat.apply( + ['r', 'n', 'b', 'q'].map(p => this.pieces()[p].moves[0])); + const [x, y] = [square_s[0], square_s[1]]; + for (let i=0; i { + this.turn = C.GetOppCol(color); + this.movesCount++; + }; + if (this.movesCount <= 1) { + toNextPlayer(); + return; + } + const captureUndef = ( + move.vanish.length == 2 && + move.vanish[1].c != color && + move.vanish[1].p == 'u' + ); + if (typeof move.start.x == "number" && !captureUndef) + // Normal move (including Teleport) + super.postPlay(move); + else if (typeof move.start.x == "string") { + this.reserve[color][move.appear[0].p]--; + if (move.vanish.length == 1 && move.vanish[0].p == 'u') + this.definition = move.end; + this.subTurn++; + } + else { + this.subTurn = 0; + this.captureUndef = move.end; + toNextPlayer(); + } + } + + isLastMove() { + return true; //called only on normal moves (not Teleport) + } + + getCurrentScore(move_s) { + return (this.movesCount <= 2 ? "*" : super.getCurrentScore(move_s)); + } + +};