/// <summary> /// Generates random planet positions. /// </summary> private List <Star> GenerateStarfield(int width, int height, int clusterCount, int clusterRadius, int clusteredStarCount, int voidStarCount, int minDistance) { //Create variables Random rnd = new Random((int)DateTime.Now.Ticks); List <Cluster> clusters = new List <Cluster>(); List <Star> stars = new List <Star>(); //Create clusters for (int i = 0; i < clusterCount; i++) { while (true) { //Generate candidates double candidateX = rnd.NextDouble() * width; double candidateY = rnd.NextDouble() * height; //Validate candidate coordinates - if they fail validation, we'll stay in the loop and iterate once more bool failedValidation = false; //Rule 1 - Clusters may not overlap with the map edge if (candidateX - clusterRadius < 0 || candidateX + clusterRadius > width || candidateY - clusterRadius < 0 || candidateY + clusterRadius > height) { failedValidation = true; } if (failedValidation) { continue; } //Rule 2 - Clusters may not overlap with each other foreach (Cluster cluster in clusters) { if (DistanceCalculator.GetDistance(candidateX, candidateY, cluster.X, cluster.Y) < 2 * clusterRadius) { failedValidation = true; } } if (failedValidation) { continue; } //The cluster passed clusters.Add(new Cluster() { X = candidateX, Y = candidateY }); break; } } //Create stars within clusters for (int i = 0; i < clusteredStarCount; i++) { while (true) { //Select a cluster Cluster selectedCluster = clusters[rnd.Next(0, clusters.Count)]; //Generate a position within the radius of the cluster //Get polar coordinates (to express being in the cluster's radius //these coordinates are interpreted as being relative to the cluster) double distance = rnd.NextDouble() * clusterRadius; double angle = rnd.NextDouble() * Math.PI * 2; //Convert polar coordinates to cartesian coordinates double candidateX = distance * Math.Cos(angle); double candidateY = distance * Math.Sin(angle); //Add cluster's coordinates to make these absolute coordinates candidateX += selectedCluster.X; candidateY += selectedCluster.Y; //Validate candidate coordinates - if they fail validation, we'll stay in the loop and iterate once more bool failedValidation = false; //Rule 1 - Stars may not be closer to each other than the specified minimum distance. foreach (Star star in stars) { if (DistanceCalculator.GetDistance(candidateX, candidateY, star.X ?? 0, star.Y ?? 0) < minDistance) { failedValidation = true; } } if (failedValidation) { continue; } //The star passed stars.Add(new Star() { Name = StarNameGenerator.GetStarName(), Guid = Guid.NewGuid(), X = candidateX, Y = candidateY }); break; } } //Create stars in the void between clusters for (int i = 0; i < voidStarCount; i++) { while (true) { //Get candidate coordinates double candidateX = rnd.NextDouble() * width; double candidateY = rnd.NextDouble() * height; //Validate candidate coordinates - if they fail validation, we'll stay in the loop and iterate once more bool failedValidation = false; //Rule 1 - Stars may not be closer to each other than the specified minimum distance. foreach (Star star in stars) { if (DistanceCalculator.GetDistance(candidateX, candidateY, star.X ?? 0, star.Y ?? 0) < minDistance) { failedValidation = true; } } if (failedValidation) { continue; } //The star passed stars.Add(new Star() { Name = StarNameGenerator.GetStarName(), Guid = Guid.NewGuid(), X = candidateX, Y = candidateY }); break; } } //Done return(stars); }
static void Main(string[] args) { StarNameGenerator generator = new StarNameGenerator(); Console.WriteLine("-- Generating 20 names with following format: V,C,V,C,FA"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("V,C,V,C,FA"))); } Console.WriteLine("\n\n\n-- Generating 20 names with following format: C,V,C,V,FA"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("C,V,C,V,FA"))); } Console.WriteLine("\n\n\n-- Generating 20 names with following format: VD,CD,V,C"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("VD,CD,V,C"))); } Console.WriteLine("\n\n\n-- Generating 20 names with following format: CD,VD,C,V"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("CD,VD,C,V"))); } Console.WriteLine("\n\n\n-- Generating 20 names with following format: V,C,V,C"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("V,C,V,C"))); } Console.WriteLine("\n\n\n-- Generating 20 names with following format: C,V,C,V"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName("C,V,C,V"))); } Console.WriteLine("\n\n\n-- Generating 20 names with prefix Greek letter names (i.e Alpha, Epsilon, etc): (format) GLN, ,C,V,C,V"); for (int i = 0; i < 20; i++) { if (i % 5 == 0) { Console.Write("\n\n"); } Console.Write(string.Format("{0}, ", generator.GenerateName())); } Console.WriteLine("\n"); }