using Assets.Common; using Assets.Map; using Assets.Voronoi; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Assets.Scripts { public class City { public Graph startGraph { get; set; } public List sitesList { get; set; } public Graph roads { get; set; } = new Graph(); public List<(int, int)> boundariesEdges { get; set; } public City(Graph startGraph) { this.startGraph = startGraph; this.sitesList = new List(); this.boundariesEdges = new List<(int, int)>(); } public City(Graph startGraph, List sitesList) : this(startGraph) { this.sitesList = sitesList; } public void AddSite(Site site) { sitesList.Add(site); FixBoundaryEdges(site); } private void FixBoundaryEdges(Site site) { var a = boundariesEdges; var b = site.Edges.Select(x => x.Item1 < x.Item2 ? x : (x.Item2, x.Item1)); boundariesEdges = a.Union(b).Except(a.Intersect(b)).ToList(); } public void CreateRoadGraph(IList points) { roads = new Graph { Vertices = sitesList.SelectMany(site => site.Vertices.Select(i => points[i]).Append(site.Point)).ToList(), }; } } [Serializable] public class GraphGeneratorDebug { public bool displayVertices = false; public bool displayCrossroads = true; public bool displayEdges = false; public bool displayCities = true; public bool displayCityRoads = true; } [RequireComponent(typeof(GraphGenerator))] public class CityGenerator : MonoBehaviour { private System.Random _random; private Graph _voronoiGraph; private Graph _locationGraph; private Graph _basicGraph; private List verticesForRoads; private List verticesForCitites; public GraphGeneratorDebug debug; public City city; public List cities = new List(); public void Start() { Reset(); } public void Reset() { var graphGenerator = GetComponent(); _random = new System.Random(graphGenerator.seed); cities = new List(); } public void NewCity() { cities.Add(CreateCity(LocateCities()[_random.Next(0, 10)], _random.Next(0, 10))); } public void Generate() { var graphGenerator = GetComponent(); graphGenerator.Generate(); _basicGraph = graphGenerator.VoronoiGenerator.Delaunay.Morph(l => l); _voronoiGraph = graphGenerator.VoronoiGenerator.Voronoi; _locationGraph = graphGenerator.LocationGenerator.Result; verticesForCitites = LocateCities(); foreach (var index in verticesForCitites) { cities.Add(CreateCity(index, _random.Next(0, 10))); } } private void DisplayGraphVertices(Graph graph) { var vertices = graph.Vertices.Select(p => p.ToVector3()); var offset = Vector3.right; foreach (var (v, i) in vertices.Select((x, i) => (x, i))) { Gizmos.DrawSphere(v, 1); } } private void DisplayGraphCrossroads(Graph graph, List vertices) { foreach (var v in vertices.Select(i => graph.Vertices[i].ToVector3())) { Gizmos.DrawSphere(v, 1); } } private void DisplayGraphCities(List cities) { foreach (City city in cities) { Gizmos.color = Color.magenta; foreach (var (a, b) in city.boundariesEdges) { Gizmos.DrawLine(_voronoiGraph.Vertices[a].ToVector3(), _voronoiGraph.Vertices[b].ToVector3()); } foreach (var a in city.sitesList) Gizmos.DrawSphere(a.Point.ToVector3(), 1); } } private void DisplayGraphEdges(Graph graph) { var edges = graph.Edges .Select(edge => (graph.Vertices[edge.Item1], graph.Vertices[edge.Item2])) .Select(edge => (edge.Item1.ToVector3(), edge.Item2.ToVector3())); foreach (var (s, e) in edges) Gizmos.DrawLine(s, e); } private void OnDrawGizmos() { if (debug.displayVertices) { Gizmos.color = Color.white; DisplayGraphVertices(_basicGraph.Morph(l => l.Point)); } if (debug.displayEdges) { Gizmos.color = Color.white; DisplayGraphEdges(_basicGraph.Morph(l => l.Point)); } if (debug.displayCrossroads) { Gizmos.color = Color.magenta; DisplayGraphCrossroads(_basicGraph.Morph(l => l.Point), verticesForRoads); } if (debug.displayCities) { Gizmos.color = Color.magenta; DisplayGraphCities(cities); } if (debug.displayCityRoads) { Gizmos.color = Color.blue; foreach (var city in cities) DisplayGraphVertices(city.roads); } } List CountProbablitityOfCity(List vertices) { List probabilities = new List(); vertices.ForEach(v => probabilities.Add((v % 2 == 0 ? _random.Next(0, 50) : _random.Next(50, 100)))); return probabilities; } List LocateCities() { // var verticesForCitites = CountProbablitityOfCity(ChoosePoints(20)); // verticesForCitites.Sort(); // return verticesForCitites.GetRange(0, 10); return ChoosePoints(20); } City CreateCity(int vertex, int size) { City newCity = new City(_basicGraph); var site = _basicGraph.Vertices[vertex]; var sites = new List(); var location = site.Location; for (int i = 0; i < size - 1; i++) { location = site.Location; var neighbours = _basicGraph.Neighbours(site.Index).Select(j => _basicGraph.Vertices[j]).Where(s => s.Location == location).ToList(); site = neighbours[_random.Next(neighbours.Count)]; sites.Add(site); } foreach (var s in sites.Distinct()) { newCity.AddSite(s); } newCity.CreateRoadGraph(_voronoiGraph.Vertices); return newCity; } List ChoosePoints(int number) { var vertices = new List(); for (int i = 0; i < number; i++) { var randomLocation = _locationGraph.Vertices[_random.Next(1, _locationGraph.Vertices.Count())]; var count = randomLocation.Sites.Count(); Site randomPoint; randomPoint = randomLocation.Sites[_random.Next(0, count)]; vertices.Add(randomPoint.Index); } return vertices; } List ChoosePoints(int number, Graph graph) { var vertices = new List(); for (int i = 0; i < number; i++) { var randomLocation = _locationGraph.Vertices[_random.Next(1, _locationGraph.Vertices.Count())]; var count = randomLocation.Sites.Count(); Site randomPoint; randomPoint = randomLocation.Sites[_random.Next(0, count)]; vertices.Add(randomPoint.Index); } return vertices; } void ConnectPointIntoRoads(/*punkty*/) { // spanning tree } void AddLanesToRoads() { // ergo dodaj randomowe połączenia xd } } }