diff --git a/src/utility/const.ts b/src/utility/const.ts index 12fc01764..97ce3c8b4 100644 --- a/src/utility/const.ts +++ b/src/utility/const.ts @@ -2,9 +2,42 @@ import { Point } from './pointfacade'; export const HEX_WIDTH_PX = 90; export const HEX_HEIGHT_PX = (HEX_WIDTH_PX / Math.sqrt(3)) * 2 * 0.75; + export function offsetCoordsToPx(point: Point) { return { x: (point.y % 2 === 0 ? point.x + 0.5 : point.x) * HEX_WIDTH_PX, y: point.y * HEX_HEIGHT_PX, }; } + +const n2_16 = Math.pow(2, 16); + +function isValid(point: Point) { + return 0 <= point.x && point.x < n2_16 && 0 <= point.y && point.y < n2_16; +} + +export function offsetNeighbors(point: Point): Point[] { + if (point.y % 2 === 0) { + return [ + { x: point.x + 1, y: point.y }, + { x: point.x + 1, y: point.y + 1 }, + { x: point.x, y: point.y + 1 }, + { x: point.x - 1, y: point.y }, + { x: point.x, y: point.y - 1 }, + { x: point.x + 1, y: point.y - 1 }, + ].filter(isValid); + } else { + return [ + { x: point.x + 1, y: point.y }, + { x: point.x, y: point.y + 1 }, + { x: point.x - 1, y: point.y + 1 }, + { x: point.x - 1, y: point.y }, + { x: point.x - 1, y: point.y - 1 }, + { x: point.x, y: point.y - 1 }, + ].filter(isValid); + } +} + +export function hashOffsetCoords(point: Point) { + return (point.x << 16) ^ point.y; +} diff --git a/src/utility/pointfacade.ts b/src/utility/pointfacade.ts index e9b28e827..4d4a5528e 100644 --- a/src/utility/pointfacade.ts +++ b/src/utility/pointfacade.ts @@ -1,5 +1,6 @@ import { Creature } from '../creature'; import { Drop } from '../drop'; +import { hashOffsetCoords as hash } from './const'; import { Trap } from './trap'; export type Point = { @@ -22,10 +23,10 @@ type PointFacadeConfig = { }; class PointSet { - s: Set; + s: Set; config: PointFacadeConfig; - constructor(s: Set, config: PointFacadeConfig) { + constructor(s: Set, config: PointFacadeConfig) { this.s = s; this.config = config; } @@ -60,7 +61,7 @@ export class PointFacade { } getBlockedSet(): PointSet { - const blockedSet = new Set(); + const blockedSet = new Set(); for (const c of this.config.getCreatures()) { for (const point of this.config.getCreatureBlockedPoints(c)) { blockedSet.add(hash(point)); @@ -87,9 +88,11 @@ export class PointFacade { getCreaturesAt(point: Point | Creature | Point[] | number, y = 0) { const config = this.config; - const points: Point[] = normalize(point, y, this.config); - const pointsToStr = points.map(hash).join(''); - const hasPoint = (p: Point) => pointsToStr.indexOf(hash(p)) !== -1; + const points: Set = normalize(point, y, this.config).reduce((s, p) => { + s.add(hash(p)); + return s; + }, new Set()); + const hasPoint = (p: Point) => points.has(hash(p)); return config .getCreatures() @@ -103,9 +106,11 @@ export class PointFacade { getTrapsAt(point: Point | Creature | Point[] | number, y = 0) { const config = this.config; - const points: Point[] = normalize(point, y, this.config); - const pointsToStr = points.map(hash).join(''); - const hasPoint = (p: Point) => pointsToStr.indexOf(hash(p)) !== -1; + const points: Set = normalize(point, y, this.config).reduce((s, p) => { + s.add(hash(p)); + return s; + }, new Set()); + const hasPoint = (p: Point) => points.has(hash(p)); return config .getTraps() @@ -119,9 +124,11 @@ export class PointFacade { getDropsAt(point: Point | Creature | Point[] | number, y = 0) { const config = this.config; - const points: Point[] = normalize(point, y, this.config); - const pointsToStr = points.map(hash).join(''); - const hasPoint = (p: Point) => pointsToStr.indexOf(hash(p)) !== -1; + const points: Set = normalize(point, y, this.config).reduce((s, p) => { + s.add(hash(p)); + return s; + }, new Set()); + const hasPoint = (p: Point) => points.has(hash(p)); return config .getDrops() @@ -133,10 +140,6 @@ export class PointFacade { } } -function hash(point: Point) { - return `(${point.x},${point.y})`; -} - function getMissingConfigRequirements(config: PointFacadeConfig): string[] { const missing: string[] = []; if (!config.getCreatures) {