using System.Collections.Generic;
using UnityEngine;
namespace MazeGen
{
///
/// Uniform grid bucket index over Room positions, so "which rooms are near this point"
/// stays cheap even once the maze has thousands of rooms, instead of scanning all of them.
///
public class SpatialRoomIndex
{
private readonly float _cellSize;
private readonly Dictionary<(int x, int y), List> _cells = new Dictionary<(int, int), List>();
public SpatialRoomIndex(float cellSize)
{
_cellSize = Mathf.Max(cellSize, 0.01f);
}
private (int, int) CellOf(Vector2 position) =>
(Mathf.FloorToInt(position.x / _cellSize), Mathf.FloorToInt(position.y / _cellSize));
public void Add(Room room)
{
var cell = CellOf(room.Position);
if (!_cells.TryGetValue(cell, out var list))
{
list = new List();
_cells[cell] = list;
}
list.Add(room);
}
///
/// Yields every registered room whose bucket falls within `radius` of `position`.
/// This is a broad-phase filter - callers still need an exact distance check.
///
public IEnumerable QueryNearby(Vector2 position, float radius)
{
var (cx, cy) = CellOf(position);
int cellRadius = Mathf.CeilToInt(radius / _cellSize) + 1;
for (int dx = -cellRadius; dx <= cellRadius; dx++)
{
for (int dy = -cellRadius; dy <= cellRadius; dy++)
{
if (_cells.TryGetValue((cx + dx, cy + dy), out var list))
{
foreach (var room in list)
yield return room;
}
}
}
}
}
}