UNPKG

@gamepark/rules-api

Version:

API to implement the rules of a board game

192 lines 7.85 kB
/** * The different coordinates systems available to describe a Hexagonal Grid. * See https://www.redblobgames.com/grids/hexagons/#coordinates */ export var HexGridSystem; (function (HexGridSystem) { HexGridSystem[HexGridSystem["Axial"] = 0] = "Axial"; HexGridSystem[HexGridSystem["OddQ"] = 1] = "OddQ"; HexGridSystem[HexGridSystem["EvenQ"] = 2] = "EvenQ"; HexGridSystem[HexGridSystem["OddR"] = 3] = "OddR"; HexGridSystem[HexGridSystem["EvenR"] = 4] = "EvenR"; })(HexGridSystem || (HexGridSystem = {})); /** * Converts {@link HexGridSystem.OddQ} coordinates into {@link HexGridSystem.Axial} coordinates */ export const oddQToAxial = ({ x, y }) => ({ x, y: y - (x - (x & 1)) / 2 }); /** * Converts {@link HexGridSystem.Axial} coordinates into {@link HexGridSystem.OddQ} coordinates */ export const axialToOddQ = ({ x, y }) => ({ x, y: y + (x - (x & 1)) / 2 }); /** * Converts {@link HexGridSystem.EvenQ} coordinates into {@link HexGridSystem.Axial} coordinates */ export const evenQToAxial = ({ x, y }) => ({ x, y: y - (x + (x & 1)) / 2 }); /** * Converts {@link HexGridSystem.Axial} coordinates into {@link HexGridSystem.EvenQ} coordinates */ export const axialToEvenQ = ({ x, y }) => ({ x, y: y + (x + (x & 1)) / 2 }); /** * Converts {@link HexGridSystem.OddR} coordinates into {@link HexGridSystem.Axial} coordinates */ export const oddRToAxial = ({ x, y }) => ({ y, x: x - (y - (y & 1)) / 2 }); /** * Converts {@link HexGridSystem.Axial} coordinates into {@link HexGridSystem.OddR} coordinates */ export const axialToOddR = ({ x, y }) => ({ y, x: x + (y - (y & 1)) / 2 }); /** * Converts {@link HexGridSystem.EvenR} coordinates into {@link HexGridSystem.Axial} coordinates */ export const evenRToAxial = ({ x, y }) => ({ y, x: x - (y + (y & 1)) / 2 }); /** * Converts {@link HexGridSystem.Axial} coordinates into {@link HexGridSystem.EvenR} coordinates */ export const axialToEvenR = ({ x, y }) => ({ y, x: x + (y + (y & 1)) / 2 }); /** * Convert any {@link HexGridSystem} coordinates to {@link HexGridSystem.Axial} * @param hex Coordinates to convert * @param system System of the coordinates * @return Coordinates in {@link HexGridSystem.Axial} */ export function hexToAxial(hex, system) { switch (system) { case HexGridSystem.OddQ: return oddQToAxial(hex); case HexGridSystem.EvenQ: return evenQToAxial(hex); case HexGridSystem.OddR: return oddRToAxial(hex); case HexGridSystem.EvenR: return evenRToAxial(hex); default: return hex; } } /** * Convert {@link HexGridSystem.Axial} coordinates to any other {@link HexGridSystem} * @param hex Axial coordinates to convert * @param system Destination coordinates system * @return Coordinates converted in the description system */ export function hexFromAxial(hex, system) { switch (system) { case HexGridSystem.OddQ: return axialToOddQ(hex); case HexGridSystem.EvenQ: return axialToEvenQ(hex); case HexGridSystem.OddR: return axialToOddR(hex); case HexGridSystem.EvenR: return axialToEvenR(hex); default: return hex; } } /** * Rotate hexagonal coordinates. * @param vector Vector to rotate * @param rotation Number of 60 degrees rotations to apply (1 = 60°, 2 = 120°...) * @param system The coordinates system used * @return the rotated vector */ export function hexRotate(vector, rotation = 0, system = HexGridSystem.Axial) { if (system !== HexGridSystem.Axial) return hexFromAxial(hexRotate(hexToAxial(vector, system), rotation), system); switch (rotation % 6) { case 1: return { x: -vector.y, y: vector.x + vector.y }; case 2: // noinspection JSSuspiciousNameCombination return { x: -vector.x - vector.y, y: vector.x }; case 3: return { x: -vector.x, y: -vector.y }; case 4: // noinspection JSSuspiciousNameCombination return { x: vector.y, y: -vector.x - vector.y }; case 5: return { x: vector.x + vector.y, y: -vector.x }; default: return vector; } } /** * Get the distance between 2 hexagons, i.e. the minimum number of hexagons to cross to got from hex1 to hex2. * @param hex1 First hexagon coordinates * @param hex2 Second hexagon coordinates * @param system The coordinates system used * @return the distance between the hexagons */ export function getDistanceBetweenHex(hex1, hex2, system = HexGridSystem.Axial) { if (system !== HexGridSystem.Axial) { return getDistanceBetweenHex(hexToAxial(hex1, system), hexToAxial(hex2, system)); } return (Math.abs(hex1.x - hex2.x) + Math.abs(hex1.x - hex2.x + hex1.y - hex2.y) + Math.abs(hex1.y - hex2.y)) / 2; } /** * Get all the hexagons that are exactly at a specific distance from a given hexagon. * @param hex Coordinates of the hexagon * @param distance Distance of the hexagons we want * @param system The coordinates system used * @return the list of the hexagons found at distance from given hex */ export function getHexagonsAtDistance(hex, distance, system = HexGridSystem.Axial) { if (system !== HexGridSystem.Axial) { return getHexagonsAtDistance(hexToAxial(hex, system), distance, HexGridSystem.Axial).map((hex) => hexFromAxial(hex, system)); } if (distance <= 0) return [hex]; const result = []; let currentHex = { x: hex.x - distance, y: hex.y }; const vectors = [{ x: 1, y: -1 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: -1, y: 1 }, { x: -1, y: 0 }, { x: 0, y: -1 }]; for (const vector of vectors) { for (let j = 0; j < distance; j++) { result.push(currentHex); currentHex = hexTranslate(currentHex, vector); } } return result; } /** * Translate hexagonal coordinates by a vector. * @param hex Coordinates of the hexagon to translate * @param vector Vector of the translation * @param system The coordinates system used * @return The coordinates of the hexagon after the translation */ export function hexTranslate(hex, vector, system = HexGridSystem.Axial) { if (system !== HexGridSystem.Axial) return hexFromAxial(hexTranslate(hexToAxial(hex, system), hexToAxial(vector, system)), system); return ({ x: hex.x + vector.x, y: hex.y + vector.y }); } /** * Get the coordinates that will be covered by a polyhex tile when at a specific grid location. * @param polyhex Coordinates occupied by the polyhex without any rotation in given coordinates system * @param location Location of the polyhex on the grid (x, y, and rotation) * @param system The coordinates system used for the polyhex description and the location * @return coordinates in the grid covered when the polyhex has this location */ export function getPolyhexSpaces(polyhex, location, system = HexGridSystem.Axial) { const vector = { x: location.x ?? 0, y: location.y ?? 0 }; return polyhex .map(hex => hexRotate(hex, location.rotation ?? 0, system)) .map(hex => hexTranslate(hex, vector, system)); } /** * Get the coordinates of the 6 hexagons adjacent to a given hexagon. * @param hex Coordinates of the hexagon * @param system Coordinates system */ export function getAdjacentHexagons(hex, system = HexGridSystem.Axial) { if (system !== HexGridSystem.Axial) { return getAdjacentHexagons(hexToAxial(hex, system)).map(((hex) => hexFromAxial(hex, system))); } return [ { x: hex.x + 1, y: hex.y }, { x: hex.x, y: hex.y + 1 }, { x: hex.x - 1, y: hex.y + 1 }, { x: hex.x - 1, y: hex.y }, { x: hex.x, y: hex.y - 1 }, { x: hex.x + 1, y: hex.y - 1 } ]; } //# sourceMappingURL=grid.hex.util.js.map