using System; using System.Collections.Generic; using Assets.Voronoi; using Random = System.Random; namespace Assets.Map { public class LocationGenerator { private readonly Graph _sites; private readonly Graph _locations; private readonly List<(int, Location)> _queue = new List<(int, Location)>(); private readonly Random _random; public Graph Sites => _sites; public Graph Result => _locations; public bool Done => _queue.Count == 0; public LocationGenerator(List locations, Graph sites, Random random = null) { _sites = sites.Morph(s => new LocationSite(s)); _locations = new Graph { Vertices = new List(locations) }; _random = random ?? new Random(); } public void SetLocation(int vertex, Location location) { location.AddSite(_sites.Vertices[vertex]); foreach (var neighbour in _sites.Neighbours(vertex)) if (_sites.Vertices[neighbour].Location == null) _queue.Add((neighbour, location)); else if (location != _sites.Vertices[neighbour].Location) _locations.AddEdge( _locations.Vertices.IndexOf(location), _locations.Vertices.IndexOf(_sites.Vertices[neighbour].Location) ); } private (int, Location) Dequeue() { while (_queue.Count > 0) { var index = _random.Next(_queue.Count); var pair = _queue[index]; _queue.RemoveAt(index); if (_sites.Vertices[pair.Item1].Location == null) return pair; } throw new Exception("No more elements."); } public void Step() { try { var (vertex, location) = Dequeue(); SetLocation(vertex, location); } catch (Exception ex) { } } } }