@gamepark/rules-api
Version:
API to implement the rules of a board game
82 lines • 3.42 kB
JavaScript
import { getHexagonsAtDistance, HexGridSystem, hexRotate, hexTranslate } from './grid.hex.util';
/**
* Class to work on Polyhex (multiple hexagons linked together)
*/
export class Polyhex {
grid;
system = HexGridSystem.Axial;
xMin = 0;
yMin = 0;
isEmpty = (value) => value == null; // true for null and undefined
constructor(grid, config) {
this.grid = grid;
this.system = config?.system ?? this.system;
this.xMin = config?.xMin ?? this.xMin;
this.yMin = config?.yMin ?? this.yMin;
this.isEmpty = config?.isEmpty ?? this.isEmpty;
}
get xMax() {
return Math.max(...this.grid.map((line) => line.length)) + this.xMin - 1;
}
get yMax() {
return this.grid.length + this.yMin - 1;
}
getValue(coordinates) {
return this.grid[coordinates.y - this.yMin]?.[coordinates.x - this.xMin];
}
/**
* Utility function to merge multiple polyhex together to create a bigger polyhex: it merges given polyhex grid in current polyhex.
* @param polyhex Polyhex to merge in the current polyhex
* @param location Location to merge the new polyhex in
* @param onOverlap Callback function when a non-empty value is erased
*/
merge(polyhex, location = {}, onOverlap = () => {
}) {
for (let y = 0; y < polyhex.length; y++) {
for (let x = 0; x < polyhex[y].length; x++) {
if (!this.isEmpty(polyhex[y][x])) {
const rotatedCoordinates = hexRotate({ x, y }, location.rotation, this.system);
const coordinates = hexTranslate(rotatedCoordinates, { x: location.x ?? 0, y: location.y ?? 0 }, this.system);
while (coordinates.y < this.yMin) {
this.grid.unshift([]);
this.yMin--;
}
while (coordinates.x < this.xMin) {
for (const line1 of this.grid) {
line1.unshift(undefined);
}
this.xMin--;
}
if (!this.grid[coordinates.y - this.yMin]) {
this.grid[coordinates.y - this.yMin] = [];
}
if (this.grid[coordinates.y - this.yMin][coordinates.x - this.xMin]) {
onOverlap(x, y);
}
this.grid[coordinates.y - this.yMin][coordinates.x - this.xMin] = polyhex[y][x];
}
}
}
}
/**
* Get the minimum distance from given hexagon to a hexagon of the polyhex that matches given predicate
* @param hex Starting hexagon
* @param predicate The predicate to match (not empty by default)
* @returns the minimum distance found
*/
getDistance(hex, predicate = (value) => !this.isEmpty(value)) {
let distance = 0;
const maxDistance = this.xMax + this.yMax - this.xMin - this.yMin;
while (distance < maxDistance) {
const hexagonsAtDistance = getHexagonsAtDistance(hex, distance, this.system);
if (hexagonsAtDistance.some((hex) => predicate(this.getValue(hex)))) {
return distance;
}
else {
distance++;
}
}
return Infinity;
}
}
//# sourceMappingURL=polyhex.util.js.map