public static int GenerateNumberOfSentients(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 80) return 1;
            else if (percentage <= 90) return 2;
            else if (percentage <= 95) return die.Roll(1, 2) + 1;
            return die.Roll(2, 3);
        }
        public static CelestialSatelliteType GenerateCelestialSatelliteType(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 45) return CelestialSatelliteType.Moon;
            else if (percentage <= 80) return CelestialSatelliteType.Rings;
            else if (percentage <= 95) return CelestialSatelliteType.GasCloud;
            return CelestialSatelliteType.ArtificialBody;
        }
        public static SentientSpecies Generate(Dice die)
        {
            SentientSpecies sentient = new SentientSpecies();
            sentient.TechLevel = GenerateCivilizationTechLevel(die);

            #region Generate Species Physiology
            int maxNumberOfAnimalClassifications = GenerateMaxNumberOfAnimalClassifications(die);
            while (true)
            {
                if (sentient.Classifications.Count >= maxNumberOfAnimalClassifications) break;
                AnimalClassification classification = GenerateAnimalClassification(die);

                bool acceptableClassification = true;
                foreach (var c in sentient.Classifications)
                {
                    if (classification == c) { acceptableClassification = false; break; }
                }

                if (acceptableClassification)
                {
                    sentient.Classifications.Add(classification);
                    if (die.Roll(1, 20) < 10) break;
                }
            }
            #endregion

            #region Generate Civilization Traits
            while (true)
            {
                if (sentient.Traits.Count >= 3) break;
                CivilizationTraits trait = GenerateCivilizationTrait(die);

                bool acceptableTrait = true;
                if (sentient.Traits.Count == 0) { }
                else
                {
                    foreach (var t in sentient.Traits)
                    {
                        if (trait == t) { acceptableTrait = false; break; }
                        else if ((trait == CivilizationTraits.Imperialist && t == CivilizationTraits.PeaceKeepers) ||
                                 (trait == CivilizationTraits.PeaceKeepers && t == CivilizationTraits.Imperialist))
                        { acceptableTrait = false; break; }

                        else if ((trait == CivilizationTraits.Communist && t == CivilizationTraits.Capitalist) ||
                                 (trait == CivilizationTraits.Capitalist && t == CivilizationTraits.Communist))
                        { acceptableTrait = false; break; }
                    }
                }

                if (acceptableTrait) sentient.Traits.Add(trait);
            }
            #endregion

            return sentient;
        }
        public static LifeStage GenerateStageOfLifeT1T2(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 20) return LifeStage.NoLife;
            else if (percentage <= 30) return LifeStage.OrganicCompounds;
            else if (percentage <= 40) return LifeStage.SingleCellular;
            else if (percentage <= 75) return LifeStage.MultiCellular;
            else if (percentage <= 90) return LifeStage.SimpleLife;
            return LifeStage.ComplexLife;
        }
        public static LifeStage GenerateStageOfLife(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 10) return LifeStage.NoLife;
            else if (percentage <= 15) return LifeStage.OrganicCompounds;
            else if (percentage <= 25) return LifeStage.SingleCellular;
            else if (percentage <= 35) return LifeStage.MultiCellular;
            else if (percentage <= 60) return LifeStage.SimpleLife;
            else if (percentage <= 96) return LifeStage.ComplexLife;
            return LifeStage.SentientLife;
        }
        public StarSector Generate()
        {
            StarSector sector = new StarSector();
            Die = new Dice();

            for (int x = 0; x < WidthHeight.X; x++)
            {
                var row = new List<StarSystem>(WidthHeight.Y);
                for (int y = 0; y < WidthHeight.Y; y++)
                {
                    var starSystem = StarSystem.Generate(Die);
                    starSystem.Coordinate = new HexCoordinate(x, y);
                    row.Add(starSystem);
                }
                sector.Sector.Add(row);
            }
            return sector;
        }
        public static CelestialSatellite Generate(Dice die)
        {
            CelestialSatellite celestialSatellite = new CelestialSatellite();
            celestialSatellite.CelestialType = GenerateCelestialSatelliteType(die);
            celestialSatellite.TerraformingTier = GenerateTerraformationTier(die);

            if (celestialSatellite.TerraformingTier == TerraformationTier.Uninhabitable ||
                celestialSatellite.CelestialType == CelestialSatelliteType.GasCloud)
            {
                celestialSatellite.StageOfLife = LifeStage.NoLife;
            }
            else if (celestialSatellite.TerraformingTier == TerraformationTier.T1 ||
                     celestialSatellite.TerraformingTier == TerraformationTier.T2)
            {
                celestialSatellite.StageOfLife = GenerateStageOfLifeT1T2(die);
            }
            else celestialSatellite.StageOfLife = GenerateStageOfLife(die);

            // Calculate Resource Value
            celestialSatellite.ResourceValue = GenerateResourceValue(die);
            if (celestialSatellite.TerraformingTier == TerraformationTier.Uninhabitable) celestialSatellite.ResourceValue += die.Roll(1, 10) + 10;
            else if (celestialSatellite.TerraformingTier == TerraformationTier.T1) celestialSatellite.ResourceValue += die.Roll(1, 5);
            else if (celestialSatellite.TerraformingTier == TerraformationTier.T2) celestialSatellite.ResourceValue += die.Roll(1, 3);
            else if (celestialSatellite.TerraformingTier == TerraformationTier.T5) celestialSatellite.ResourceValue += die.Roll(1, 5) + 3;

            // Generate Sentient Species
            if (celestialSatellite.StageOfLife == LifeStage.SentientLife)
            {
                int numberOfSentients = GenerateNumberOfSentients(die);
                for (int i = 0; i < numberOfSentients; i++)
                {
                    celestialSatellite.Sentients.Add(SentientSpecies.Generate(die));
                }
            }

            return celestialSatellite;
        }
        public static TerraformationTier GenerateTerraformationTier(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 6) return TerraformationTier.Uninhabitable;
            else if (percentage <= 20) return TerraformationTier.T1;
            else if (percentage <= 35) return TerraformationTier.T2;
            else if (percentage <= 70) return TerraformationTier.T3;
            else if (percentage <= 85) return TerraformationTier.T4;
            return TerraformationTier.T5;
        }
 public static int GenerateResourceValue(Dice die)
 {
     return die.Roll(1, 10);
 }
        public static CelestialBody Generate(Dice die)
        {
            CelestialBody celestialObject = new CelestialBody();
            celestialObject.CelestialType = GenerateCelestialBodyType(die);

            // Terraforming Tier
            if (celestialObject.CelestialType == CelestialBodyType.Blackhole ||
                celestialObject.CelestialType == CelestialBodyType.SubStar ||
                celestialObject.CelestialType == CelestialBodyType.Wormhole ||
                celestialObject.CelestialType == CelestialBodyType.Comet)
            {
                celestialObject.TerraformingTier = TerraformationTier.Uninhabitable;
            }
            else celestialObject.TerraformingTier = GenerateTerraformationTier(die);

            // Stage of Life
            if (celestialObject.TerraformingTier == TerraformationTier.Uninhabitable ||
                celestialObject.CelestialType == CelestialBodyType.Blackhole ||
                celestialObject.CelestialType == CelestialBodyType.SubStar ||
                celestialObject.CelestialType == CelestialBodyType.Wormhole ||
                celestialObject.CelestialType == CelestialBodyType.Comet)
            {
                celestialObject.StageOfLife = LifeStage.NoLife;
            }
            else if (celestialObject.TerraformingTier == TerraformationTier.T1 ||
                     celestialObject.TerraformingTier == TerraformationTier.T2 ||
                     celestialObject.CelestialType == CelestialBodyType.GasPlanet)
            {
                celestialObject.StageOfLife = GenerateStageOfLifeT1T2(die);
            }
            else celestialObject.StageOfLife = GenerateStageOfLife(die);

            // Calculate Resource Value
            celestialObject.ResourceValue = GenerateResourceValue(die);
            if (celestialObject.CelestialType == CelestialBodyType.Blackhole || celestialObject.CelestialType == CelestialBodyType.Wormhole)
            {
                celestialObject.ResourceValue = 0;
            }
            else if (celestialObject.TerraformingTier == TerraformationTier.Uninhabitable) celestialObject.ResourceValue += die.Roll(1, 10) + 10;
            else if (celestialObject.TerraformingTier == TerraformationTier.T1) celestialObject.ResourceValue += die.Roll(1, 5);
            else if (celestialObject.TerraformingTier == TerraformationTier.T2) celestialObject.ResourceValue += die.Roll(1, 3);
            else if (celestialObject.TerraformingTier == TerraformationTier.T5) celestialObject.ResourceValue += die.Roll(1, 5) + 3;

            // Generate Sentient Species
            if (celestialObject.StageOfLife == LifeStage.SentientLife)
            {
                int numberOfSentients = GenerateNumberOfSentients(die);
                for (int i = 0; i < numberOfSentients; i++)
                {
                    celestialObject.Sentients.Add(SentientSpecies.Generate(die));
                }
            }

            // Generate Celestial Satellites
            if (celestialObject.CelestialType == CelestialBodyType.Comet) { }
            else if (celestialObject.CelestialType == CelestialBodyType.Wormhole) { }
            //else if (celestialObject.CelestialType == CelestialBodyType.AsteroidBelt) { }
            else
            {
                int numberOfCelestialSatellites = GenerateNumberOfCelestialSatellites(die);
                for (int i = 0; i < numberOfCelestialSatellites; i++)
                {
                    celestialObject.OrbitingSatellites.Add(CelestialSatellite.Generate(die));
                }
            }

            return celestialObject;
        }
        public static int GenerateNumberOfCelestialSatellites(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 60) return 1;
            else if (percentage <= 80) return 2;
            else if (percentage <= 95) return die.Roll(1, 4);
            return die.Roll(2, 4);
        }
        public static CelestialBodyType GenerateCelestialBodyType(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 7) return CelestialBodyType.Blackhole;
            else if (percentage <= 15) return CelestialBodyType.SubStar;
            else if (percentage <= 25) return CelestialBodyType.Comet;
            else if (percentage <= 40) return CelestialBodyType.AsteroidBelt;
            else if (percentage <= 65) return CelestialBodyType.GasPlanet;
            else if (percentage <= 95) return CelestialBodyType.TerrestrialPlanet;
            return CelestialBodyType.ArtificialPlanet;
        }
        public static int GenerateMaxNumberOfAnimalClassifications(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 75) return 1;
            else if (percentage <= 80) return die.Roll(1, 3);
            return die.Roll(2, 4);
        }
        public static CivilizationTraits GenerateCivilizationTrait(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 10)       return CivilizationTraits.Capitalist;
            else if (percentage <= 20)  return CivilizationTraits.Communist;
            else if (percentage <= 30)  return CivilizationTraits.Corporate;
            else if (percentage <= 40)  return CivilizationTraits.Explorer;
            else if (percentage <= 50)  return CivilizationTraits.Imperialist;
            else if (percentage <= 60)  return CivilizationTraits.PeaceKeepers;
            else if (percentage <= 70)  return CivilizationTraits.Philosophical;
            else if (percentage <= 80)  return CivilizationTraits.Scientist;
            else if (percentage <= 90)  return CivilizationTraits.Theocratic;
            return CivilizationTraits.Warmonger;
        }
        public static CivilizationTechLevel GenerateCivilizationTechLevel(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 10)       return CivilizationTechLevel.Cavemen;
            else if (percentage <= 20)  return CivilizationTechLevel.SpaceAge;
            else if (percentage <= 30)  return CivilizationTechLevel.BronzeAge;
            else if (percentage <= 40)  return CivilizationTechLevel.IronAge;

            else if (percentage <= 50)  return CivilizationTechLevel.IndustrialRevolution;
            else if (percentage <= 60)  return CivilizationTechLevel.AtomicAge;
            else if (percentage <= 70)  return CivilizationTechLevel.SpaceAge;
            else if (percentage <= 90)  return CivilizationTechLevel.DigitalAge;
            return CivilizationTechLevel.InterstellarAge;
        }
        public static AnimalClassification GenerateAnimalClassification(Dice die)
        {
            int percentage = die.Roll(1, 100);

            if (percentage <= 10)       return AnimalClassification.Amphibian;
            else if (percentage <= 20)  return AnimalClassification.Avian;
            else if (percentage <= 30)  return AnimalClassification.Aquatic;
            else if (percentage <= 50)  return AnimalClassification.Reptillian;
            else if (percentage <= 75)  return AnimalClassification.Mammal;
            else if (percentage <= 85)  return AnimalClassification.Rock;
            else if (percentage <= 95)  return AnimalClassification.Energy;
            else if (percentage <= 98)  return AnimalClassification.Exotic;
            return AnimalClassification.SpaceBased;
        }