using System; using System.Collections.Generic; using System.Linq; using Assets.Cities; using Assets.Common; namespace Assets.AnnotationPass { public class LocateCitiesPass : IAnnotationPass { public const string CitiesProperty = "Cities"; public const string CityProperty = "City"; private Graph<Location> _locationGraph; private Graph<MapSite> _basicGraph; private Random _random; public LocateCitiesPass(Random random = null) { _random = random ?? new Random(); } IEnumerable<int> LocateCities() { return ChoosePoints(5); } City CreateCity(int vertex, int size) { City newCity = new City(); var site = _basicGraph.Vertices[vertex]; var sites = new List<MapSite> { site }; var location = site.Metadata.GetProperty<Location>(LandmassPass.SiteLocationProperty); for (int i = 0; i < size - 1; i++) { var neighbours = _basicGraph.Neighbours(site.Index).Select(j => _basicGraph.Vertices[j]).Where(s => s.Metadata.GetProperty<Location>(LandmassPass.SiteLocationProperty) == location).ToList(); site = neighbours[_random.Next(neighbours.Count)]; sites.Add(site); } foreach (var s in sites.Distinct()) { newCity.AddSite(s); s.Metadata.SetProperty(CityProperty, newCity); } return newCity; } IEnumerable<int> ChoosePoints(int number) { var vertices = new List<int>(); for (int i = 0; i < number; i++) { var randomLocation = _locationGraph.Vertices[_random.Next(1, _locationGraph.Vertices.Count())]; var count = randomLocation.Sites.Count(); var randomPoint = randomLocation.Sites[_random.Next(0, count)]; vertices.Add(randomPoint.Index); } return vertices; } public void Annotate(Map map) { _basicGraph = map.Sites.Clone() as Graph<MapSite>; _locationGraph = map.Metadata.GetProperty<Graph<Location>>(LandmassPass.MapLocationsProperty); var cities = new List<City>(); var locations = LocateCities(); foreach (var index in locations) cities.Add(CreateCity(index, _random.Next(0, 10))); map.Metadata.SetProperty(CitiesProperty, cities); } } }