X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=variants%2FHex%2Fclass.js;h=925507eb2d7074e7ba3388d51bc7eb4df8347b27;hb=e7d409fc03a8cd8459a2b41f9fef51c0a3fb0d6d;hp=f1e3a8388f25860c31215ba49e1a5fc55bed6a4c;hpb=728cb1e3b2ae84b1cf4aaa7e66b295f77dea359e;p=xogo.git diff --git a/variants/Hex/class.js b/variants/Hex/class.js index f1e3a83..925507e 100644 --- a/variants/Hex/class.js +++ b/variants/Hex/class.js @@ -1,36 +1,256 @@ +import ChessRules from "/base_rules.js"; +import PiPo from "/utils/PiPo.js"; +import Move from "/utils/Move.js"; + +export default class HexRules extends ChessRules { + + static get Options() { + return { + input: [ + { + label: "Board size", + variable: "bsize", + type: "number", + defaut: 11 + }, + { + label: "Swap", + variable: "swap", + type: "checkbox", + defaut: true + } + ] + }; + } + + get hasFlags() { + return false; + } + get hasEnpassant() { + return false; + } + get hasReserve() { + return false; + } + + get noAnimate() { + return true; + } + + doClick(coords) { + if ( + this.playerColor != this.turn || + ( + this.board[coords.x][coords.y] != "" && + (!this.options["swap"] || this.movesCount >= 2) + ) + ) { + return null; + } + let res = new Move({ + start: {x: coords.x, y: coords.y}, + appear: [ + new PiPo({ + x: coords.x, + y: coords.y, + c: this.turn, + p: 'p' + }) + ], + vanish: [] + }); + if (this.board[coords.x][coords.y] != "") { + res.vanish.push( + new PiPo({ + x: coords.x, + y: coords.y, + c: C.GetOppCol(this.turn), + p: 'p' + }) + ); + } + return res; + } + + genRandInitFen() { + // NOTE: size.x == size.y (square boards) + const emptyCount = C.FenEmptySquares(this.size.x); + return (emptyCount + "/").repeat(this.size.x).slice(0, -1) + " w 0"; + } + getSvgChessboard() { - const flipped = (this.playerColor == 'b'); + // NOTE: with small margin seems nicer + let width = 173.2 * this.size.y + 173.2 * (this.size.y-1) / 2 + 30, + height = 50 + Math.floor(150 * this.size.x) + 30, + min_x = -86.6 - 15, + min_y = -100 - 15; + if (this.size.ratio < 1) { + // Rotate by 30 degrees to display vertically + [width, height] = [height, width]; + [min_x, min_y] = [min_y, min_x]; + } let board = ` `; + board += "`; + board += ` + `; } } - board += ""; + board += ``; return board; } -// neutral-light neutral-dark --> specify per variant in CSS file - getSquareColorClass(i, j) { - return ((i+j) % 2 == 0 ? "light-square": "dark-square"); + setupPieces() { + for (let i=0; i { + if (e.touches && e.touches.length > 1) + e.preventDefault(); + const cd = this.idToCoords(e.target.id); + if (cd) { + const move = this.doClick(cd); + if (move) + this.buildMoveStack(move); + } + }; + + if ('onmousedown' in window) { + document.addEventListener("mousedown", mousedown); + document.addEventListener("wheel", + (e) => this.rescale(e.deltaY < 0 ? "up" : "down")); + } + if ('ontouchstart' in window) + document.addEventListener("touchstart", mousedown, {passive: false}); + } + + get size() { + const baseRatio = 1.6191907514450865; //2801.2 / 1730, "widescreen" + const rotate = window.innerWidth < window.innerHeight; //"vertical screen" + return { + x: this.options["bsize"], + y: this.options["bsize"], + ratio: (rotate ? 1 / baseRatio : baseRatio) + }; + } + + play(move) { + this.playOnBoard(move); + this.movesCount++; + this.turn = C.GetOppCol(this.turn); + } + + getCurrentScore(move) { + const oppCol = C.GetOppCol(this.turn); + // Search for connecting path of opp color: + let explored = {}, component; + let min, max; + const getIndex = (x, y) => x + "." + y; + // Explore one connected component: + const neighborsSearch = ([x, y], index) => { + // Let's say "white" connects on x and "black" on y + const z = (oppCol == 'w' ? x : y); + if (z < min) + min = z; + if (z > max) + max = z; + explored[index] = true; + component[index] = true; + for (let [dx, dy] of super.pieces()['k'].moves[0].steps) { + const [nx, ny] = [x + dx, y + dy]; + const nidx = getIndex(nx, ny); + if ( + this.onBoard(nx, ny) && + this.getColor(nx, ny) == oppCol && + !component[nidx] + ) { + neighborsSearch([nx, ny], nidx); + } + } + }; + // Explore all components: + for (let i=0; i { + let elt = document.getElementById(this.coordsToId({x: v.x, y: v.y})); + elt.classList.remove("bg-" + (v.c == 'w' ? "white" : "black")); + }); + move.appear.forEach(a => { + let elt = document.getElementById(this.coordsToId({x: a.x, y: a.y})); + elt.classList.add("bg-" + (a.c == 'w' ? "white" : "black")); + }); } -// TODO: generalize base_rules.js to not assume size.x == width and size.y == height (not true here). +};