export function seededRng(seed) {
    let s = seed % 2147483647;
    if (s <= 0) s += 2147483646;
    return function () {
        s = (s * 16807) % 2147483647;
        return (s - 1) / 2147483646;
    };
}

// Maze generation (recursive backtracker): 0 path, 1 wall
export function generateMazeGrid(w, h, seed) {
    if (w % 2 === 0) w += 1;
    if (h % 2 === 0) h += 1;
    const rng = seededRng(seed);
    const grid = Array.from({ length: h }, () => Array(w).fill(1));

    function carve(x, y) {
        grid[y][x] = 0;
        const dirs = [[0, -2], [2, 0], [0, 2], [-2, 0]];
        for (let i = dirs.length - 1; i > 0; i--) {
            const j = Math.floor(rng() * (i + 1));
            [dirs[i], dirs[j]] = [dirs[j], dirs[i]];
        }
        for (const [dx, dy] of dirs) {
            const nx = x + dx;
            const ny = y + dy;
            if (nx > 0 && nx < w - 1 && ny > 0 && ny < h - 1 && grid[ny][nx] === 1) {
                grid[y + dy / 2][x + dx / 2] = 0;
                carve(nx, ny);
            }
        }
    }

    const sx = 1 + Math.floor(rng() * ((w - 1) / 2)) * 2;
    const sy = 1 + Math.floor(rng() * ((h - 1) / 2)) * 2;
    carve(sx, sy);

    const extra = Math.max(0, Math.floor((w * h) * 0.02));
    for (let i = 0; i < extra; i++) {
        const rx = 1 + Math.floor(rng() * ((w - 1) / 2)) * 2;
        const ry = 1 + Math.floor(rng() * ((h - 1) / 2)) * 2;
        const dirs = [[0, -1], [1, 0], [0, 1], [-1, 0]];
        const [dx, dy] = dirs[Math.floor(rng() * dirs.length)];
        const nx = rx + dx;
        const ny = ry + dy;
        if (nx > 0 && nx < w - 1 && ny > 0 && ny < h - 1) grid[ny][nx] = 0;
    }

    return grid;
}

export function findDeadEnds(grid) {
    const h = grid.length;
    const w = grid[0].length;
    const dead = [];
    for (let y = 1; y < h - 1; y++) {
        for (let x = 1; x < w - 1; x++) {
            if (grid[y][x] !== 0) continue;
            let neighbors = 0;
            const deltas = [[0, 1], [1, 0], [0, -1], [-1, 0]];
            for (const [dx, dy] of deltas) if (grid[y + dy][x + dx] === 0) neighbors++;
            if (neighbors === 1) dead.push([x, y]);
        }
    }
    return dead;
}
