72 lines
2.2 KiB
C#
72 lines
2.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Assets.Voronoi;
|
|
using Random = System.Random;
|
|
|
|
namespace Assets.Map
|
|
{
|
|
public class LocationGenerator
|
|
{
|
|
private readonly Graph<LocationSite> _sites;
|
|
private readonly Graph<Location> _locations;
|
|
|
|
private readonly List<(int, Location)> _queue = new List<(int, Location)>();
|
|
|
|
private readonly Random _random;
|
|
|
|
public Graph<LocationSite> Sites => _sites;
|
|
public Graph<Location> Result => _locations;
|
|
|
|
public bool Done => _queue.Count == 0;
|
|
|
|
public LocationGenerator(List<Location> locations, Graph<Site> sites, Random random = null)
|
|
{
|
|
_sites = sites.Morph(s => new LocationSite(s));
|
|
_locations = new Graph<Location> { Vertices = new List<Location>(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)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
} |