export const CELL_SIZE = 40 export const BOARD_SIZE = 15 export interface CameraState { x: number y: number zoom: number } export interface Bounds { minX: number minY: number maxX: number maxY: number } export function serializeCoord(x: number, y: number): string { return `${x}:${y}` } export function deserializeCoord(key: string): { x: number; y: number } { const [x, y] = key.split(':').map(Number) return { x, y } } export function isBoardCoordInBounds(x: number, y: number, boardSize: number): boolean { return Number.isInteger(x) && Number.isInteger(y) && x >= 0 && x < boardSize && y >= 0 && y < boardSize } export function worldToScreen( wx: number, wy: number, camera: CameraState, vw: number, vh: number, ): { x: number; y: number } { return { x: (wx - camera.x) * camera.zoom + vw / 2, y: (wy - camera.y) * camera.zoom + vh / 2, } } export function screenToWorld( sx: number, sy: number, camera: CameraState, vw: number, vh: number, ): { x: number; y: number } { return { x: (sx - vw / 2) / camera.zoom + camera.x, y: (sy - vh / 2) / camera.zoom + camera.y, } }