public Galaxy Generate(GalaxySize size, GalaxyDensity density, PlanetDistribution planetDistribution)
        {
            var edge = size.GetAttributeOfType <GalaxyEdgeAttribute>().Edge;
            var num  = density.GetAttributeOfType <BasePlanetCountAttribute>().Num;

            num = num * edge * edge / 160000;

            Galaxy galaxy = null;

            while (galaxy == null)
            {
                try
                {
                    galaxy = this.GenerateGalaxyWithDistribution(planetDistribution, edge, num);
                }
                catch (PlanetPlacementException)
                {
                    ////Retry
                }
            }

            foreach (var planet in galaxy.Planets)
            {
                this.planetGeneratorService.PopulatePlanetStats(planet);
            }

            return(galaxy);
        }
        public void GenerateShouldCreateCorrectGalaxy(
            [Values(GalaxySize.Tiny, GalaxySize.Small, GalaxySize.Medium, GalaxySize.Large, GalaxySize.Huge)] GalaxySize size,
            [Values(GalaxyDensity.Sparse, GalaxyDensity.Normal, GalaxyDensity.Dense, GalaxyDensity.Packed)] GalaxyDensity density,
            [Values(PlanetDistribution.Uniform, PlanetDistribution.FreeClumping, PlanetDistribution.UniformClumping)] PlanetDistribution distribution)
        {
            ////Arrange
            var edge = size.GetAttributeOfType <GalaxyEdgeAttribute>().Edge;
            var num  = density.GetAttributeOfType <BasePlanetCountAttribute>().Num *edge *edge / 160000;

            ////Act
            var galaxy = this.galaxyGeneratorService.Generate(size, density, distribution);

            ////Assert
            galaxy.Width.ShouldBe(edge);
            galaxy.Height.ShouldBe(edge);
            galaxy.Planets.Count.ShouldBe(num);

            foreach (var planet in galaxy.Planets)
            {
                planet.X.ShouldBeInRange(0, edge);
                planet.Y.ShouldBeInRange(0, edge);
            }
        }
        private Galaxy GenerateGalaxyWithDistribution(PlanetDistribution planetDistribution, int edge, int num)
        {
            Galaxy galaxy;

            switch (planetDistribution)
            {
            case PlanetDistribution.Uniform:
                galaxy = this.GenerateUniformInternal(edge, edge, num);
                break;

            case PlanetDistribution.FreeClumping:
                galaxy = this.GenerateFreeClumpingInternal(edge, edge, num);
                break;

            case PlanetDistribution.UniformClumping:
                galaxy = this.GenerateUniformClumpingInternal(edge, edge, num);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(planetDistribution), planetDistribution, null);
            }

            return(galaxy);
        }