/** Grid math. Origin at world center, +x east, +y south, Dir 0..3 = N,E,S,W clockwise. */ import type { Dir, Vec2 } from '../contracts'; export const DIR_VEC: ReadonlyArray = [ { x: 0, y: -1 }, // 0 N { x: 1, y: 0 }, // 1 E { x: 0, y: 1 }, // 2 S { x: -1, y: 0 }, // 3 W ]; export const GRID_MIN = -32; export const GRID_MAX = 31; /** Packs a tile into a unique number so occupancy can live in a flat Map. */ export function tileKey(x: number, y: number): number { return (x + 32768) * 65536 + (y + 32768); } export function inBounds(x: number, y: number): boolean { return x >= GRID_MIN && x <= GRID_MAX && y >= GRID_MIN && y <= GRID_MAX; } /** Footprint after rotation — facing E or W swaps width and height. */ export function footprintOf(fp: Vec2, dir: Dir): Vec2 { return dir === 1 || dir === 3 ? { x: fp.y, y: fp.x } : { x: fp.x, y: fp.y }; }