import type { FloorState, TileKind, TilePosition } from '../../domain/src/types.js' function hash(seed: string): number { let value = 2166136261 for (const c of seed) { value ^= c.charCodeAt(0); value = Math.imul(value, 16777619) } return value >>> 0 } function rng(seed: string): () => number { let state = hash(seed) || 1 return () => { state ^= state << 13; state ^= state >>> 17; state ^= state << 5; return (state >>> 0) / 4294967296 } } const key = (p: TilePosition) => `${p.x},${p.y}` export function validateFloor(floor: FloorState): boolean { if (floor.spawnTiles.length === 0 || floor.tiles.flat().filter(t => t === 'exit').length !== 1) return false const seen = new Set(), queue = [floor.spawnTiles[0]!] while (queue.length) { const p = queue.shift()!; if (seen.has(key(p))) continue; seen.add(key(p)) for (const n of [{x:p.x,y:p.y-1},{x:p.x-1,y:p.y},{x:p.x+1,y:p.y},{x:p.x,y:p.y+1}]) { if (n.x >= 0 && n.y >= 0 && n.x < floor.width && n.y < floor.height && floor.tiles[n.y]?.[n.x] !== 'wall' && !seen.has(key(n))) queue.push(n) } } return seen.has(key(floor.exitPosition)) && floor.tiles[0]?.every(t => t === 'wall') === true && floor.tiles.at(-1)?.every(t => t === 'wall') === true } export function generateFloor(seed: string): FloorState { const random = rng(seed), width = 18 + Math.floor(random() * 5), height = 11 + Math.floor(random() * 4) const tiles: TileKind[][] = Array.from({length: height}, () => Array(width).fill('wall')) const spawnW = 4 + Math.floor(random()*3), spawnH = 4 + Math.floor(random()*2) const exitW = 4 + Math.floor(random()*3), exitH = 4 + Math.floor(random()*2) const sy = 2 + Math.floor(random() * Math.max(1, height-spawnH-3)), ey = 2 + Math.floor(random() * Math.max(1, height-exitH-3)) const carve = (x:number,y:number,w:number,h:number) => { for(let yy=y;yy