From: Benjamin Auder Date: Tue, 21 Jun 2022 08:08:42 +0000 (+0200) Subject: Start Ambiguous X-Git-Url: https://git.auder.net/doc/current/%7B%7B%20asset%28%27mixstore/css/user/%7B%7B%20pkg.url%20%7D%7D?a=commitdiff_plain;h=0a36d31a3e4fd356624f70058cbafc135fbf6fba;p=xogo.git Start Ambiguous --- diff --git a/variants/Ambiguous/class.js b/variants/Ambiguous/class.js new file mode 100644 index 0000000..78d3d63 --- /dev/null +++ b/variants/Ambiguous/class.js @@ -0,0 +1,166 @@ +import ChessRules from "/base_rules.js"; +import { randInt, shuffle } from "@/utils/alea"; +import { ArrayFun } from "@/utils/array"; + +export default class AmbiguousRules extends ChessRules { + + // TODO: options + + get hasFlags() { + return false; + } + + setOtherVariables(fenParsed) { + super.setOtherVariables(fenParsed); + if (this.movesCount == 0) + this.subTurn = 2; + else + this.subTurn = 1; + } + + genRandInitFen(seed) { + const gr = new GiveawayRules( + {mode: "suicide", options: this.options, genFenOnly: true}); + return gr.genRandInitFen(seed); + } + + // Subturn 1: play a move for the opponent on the designated square. + // Subturn 2: play a move for me (which just indicate a square). + getPotentialMovesFrom([x, y]) { + const color = this.turn; + const oppCol = V.GetOppCol(color); + if (this.subTurn == 2) { + // Just play a normal move (which in fact only indicate a square) + let movesHash = {}; + return ( + super.getPotentialMovesFrom([x, y]) + .filter(m => { + // Filter promotions: keep only one, since no choice now. + if (m.appear[0].p != m.vanish[0].p) { + const hash = V.CoordsToSquare(m.start) + V.CoordsToSquare(m.end); + if (!movesHash[hash]) { + movesHash[hash] = true; + return true; + } + return false; + } + return true; + }) + .map(m => { + if (m.vanish.length == 1) m.appear[0].p = V.GOAL; + else m.appear[0].p = V.TARGET_CODE[m.vanish[1].p]; + m.appear[0].c = oppCol; + m.vanish.shift(); + return m; + }) + ); + } + // At subTurn == 1, play a targeted move for opponent + // Search for target (we could also have it in a stack...) + let target = { x: -1, y: -1 }; + outerLoop: for (let i = 0; i < V.size.x; i++) { + for (let j = 0; j < V.size.y; j++) { + if (this.board[i][j] != V.EMPTY) { + const piece = this.board[i][j][1]; + if ( + piece == V.GOAL || + Object.keys(V.TARGET_DECODE).includes(piece) + ) { + target = { x: i, y: j}; + break outerLoop; + } + } + } + } + // TODO: could be more efficient than generating all moves. + this.turn = oppCol; + const emptyTarget = (this.board[target.x][target.y][1] == V.GOAL); + if (emptyTarget) this.board[target.x][target.y] = V.EMPTY; + let moves = super.getPotentialMovesFrom([x, y]); + if (emptyTarget) { + this.board[target.x][target.y] = color + V.GOAL; + moves.forEach(m => { + m.vanish.push({ + x: target.x, + y: target.y, + c: color, + p: V.GOAL + }); + }); + } + this.turn = color; + return moves.filter(m => m.end.x == target.x && m.end.y == target.y); + } + + canIplay(x, y) { + const color = this.getColor(x, y); + return ( + (this.subTurn == 1 && ![this.turn, this.playerColor].includes(color)) || + (this.subTurn == 2 && super.canIplay(x, y)) + ); + } + + // Code for empty square target + static get GOAL() { + return 'g'; + } + + static get TARGET_DECODE() { + return { + 's': 'p', + 't': 'q', + 'u': 'r', + 'o': 'n', + 'c': 'b', + 'l': 'k' + }; + } + + static get TARGET_CODE() { + return { + 'p': 's', + 'q': 't', + 'r': 'u', + 'n': 'o', + 'b': 'c', + 'k': 'l' + }; + } + + pieces() { + // ......... + } + + atLeastOneMove() { + // Since there are no checks this seems true (same as for Magnetic...) + return true; + } + + filterValid(moves) { + return moves; + } + + getCurrentScore() { + // This function is only called at subTurn 1 + const color = V.GetOppCol(this.turn); + if (this.kingPos[color][0] < 0) return (color == 'w' ? "0-1" : "1-0"); + return "*"; + } + + play(move) { + let kingCaptured = false; + if (this.subTurn == 1) { + this.prePlay(move); + this.epSquares.push(this.getEpSquare(move)); + kingCaptured = this.kingPos[this.turn][0] < 0; + } + if (kingCaptured) move.kingCaptured = true; + V.PlayOnBoard(this.board, move); + if (this.subTurn == 2 || kingCaptured) { + this.turn = V.GetOppCol(this.turn); + this.movesCount++; + } + if (!kingCaptured) this.subTurn = 3 - this.subTurn; + } + +};