Esempio n. 1
0
        public static void GenerateTranslatedMaps(int amountToGenerate, int seedStart)
        {
            var sw = new Stopwatch();

            for (var i = seedStart; i < seedStart + amountToGenerate; i++)
            {
                sw.Restart();
                var random123 = new Random(i);
                var ca        = new CellularAutomata(64, 64, Enums.Half.Top, maxRangeToGroupPoint: 7, r: random123);
                ca.RunGenerations();
                ca.CreateImpassableTerrain(maxLength: 25, maxPathNoiseDisplacement: 1, maxWidth: 2);

                var map = new MapPhenotype(ca.Map, new Enums.Item[64, 64]);
                map.SmoothTerrain();

                var newMap = MapHelper.IncreaseSizeOfMap(map, 2);
                newMap.SmoothTerrain(random: random123);
                newMap.PlaceCliffs();

                newMap.SmoothCliffs();
                newMap.UpdateCliffPositions(Enums.Half.Top);
                newMap.SaveMapToPngFile(string.Format("map {0}_4_translated_post_smooth_cliffs", i), itemMap: false);
                Console.WriteLine(sw.ElapsedMilliseconds);
            }

            Console.ReadKey();
        }
Esempio n. 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EvolvableMap"/> class.
 /// </summary>
 /// <param name="mapSearchOptions"> The map search options.</param>
 /// <param name="mutationChance"> The mutation chance. </param>
 /// <param name="r"> The random object. </param>
 /// <param name="mapFitnessOptions"> The map fitness options. </param>
 public EvolvableMap(MapSearchOptions mapSearchOptions, double mutationChance, Random r, MapFitnessOptions mapFitnessOptions) : base(mutationChance, r)
 {
     this.MapFitnessOptions  = mapFitnessOptions;
     this.MapSearchOptions   = mapSearchOptions;
     this.convertedPhenotype = null;
     this.hasBeenConverted   = false;
     this.MapPoints          = new List <MapPoint>();
 }
Esempio n. 3
0
        /// <summary>
        /// Converts this individual onto an empty map.
        /// </summary>
        /// <param name="xSize"> The width of the map. </param>
        /// <param name="ySize"> The height of the map. </param>
        /// <returns> The <see cref="MapPhenotype"/> that corresponds to this individual.</returns>
        public MapPhenotype ConvertToPhenotype(int xSize, int ySize)
        {
            var map = new MapPhenotype(ySize, xSize);

            map = MapConversionHelper.ConvertToPhenotype(this.MapPoints, new MapSearchOptions(map, MapSearchOptions), this.Random);

            return(map);
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MapSearchOptions"/> class.
        /// </summary>
        /// <param name="mp">
        /// The map phenotype.
        /// </param>
        /// <param name="mso">
        /// The map search options to copy..
        /// </param>
        public MapSearchOptions(MapPhenotype mp, MapSearchOptions mso)
        {
            this.ChanceToAddBase                = mso.ChanceToAddBase;
            this.ChanceToAddGoldBase            = mso.ChanceToAddGoldBase;
            this.ChanceToAddDestructibleRocks   = mso.ChanceToAddDestructibleRocks;
            this.ChanceToAddXelNagaTower        = mso.ChanceToAddXelNagaTower;
            this.ChanceToRemoveElement          = mso.ChanceToRemoveElement;
            this.ChanceToAddNewElement          = mso.ChanceToAddNewElement;
            this.MaximumStartBaseDistance       = mso.MaximumStartBaseDistance;
            this.MinimumStartBaseDistance       = mso.MinimumStartBaseDistance;
            this.TooManyElementsPenalty         = mso.TooManyElementsPenalty;
            this.TooFewElementsPenalty          = mso.TooFewElementsPenalty;
            this.DisplacementAmountPerStep      = mso.DisplacementAmountPerStep;
            this.MaximumDisplacement            = mso.MaximumDisplacement;
            this.NoPathBetweenStartBasesPenalty = mso.NoPathBetweenStartBasesPenalty;
            this.MapCompletion = mso.MapCompletion;
            this.MaximumNumberOfXelNagaTowers     = mso.MaximumNumberOfXelNagaTowers;
            this.MinimumNumberOfXelNagaTowers     = mso.MinimumNumberOfXelNagaTowers;
            this.MaximumNumberOfDestructibleRocks = mso.MaximumNumberOfDestructibleRocks;
            this.MinimumNumberOfDestructibleRocks = mso.MinimumNumberOfDestructibleRocks;
            this.MaximumNumberOfRamps             = mso.MaximumNumberOfRamps;
            this.MinimumNumberOfRamps             = mso.MinimumNumberOfRamps;
            this.MaximumNumberOfBases             = mso.MaximumNumberOfBases;
            this.MinimumNumberOfBases             = mso.MinimumNumberOfBases;
            this.MinimumDegreeModifier            = mso.MinimumDegreeModifier;
            this.MaximumDegreeModifier            = mso.MaximumDegreeModifier;
            this.MinimumDistanceModifier          = mso.MinimumDistanceModifier;
            this.MaximumDistanceModifier          = mso.MaximumDistanceModifier;
            this.MinimumDistance          = mso.MinimumDistance;
            this.MaximumDistance          = mso.MaximumDistance;
            this.MinimumDegree            = mso.MinimumDegree;
            this.MaximumDegree            = mso.MaximumDegree;
            this.NotPlacedPenalty         = mso.NotPlacedPenalty;
            this.NotPlacedPenaltyModifier = mso.NotPlacedPenaltyModifier;

            this.Map = mp;
        }
Esempio n. 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MapSearchOptions"/> class.
 /// </summary>
 /// <param name="mp"> The map phenotype to search on. </param>
 /// <param name="mapCompletion"> The completion method to use when converting to phenotype. </param>
 /// <param name="chanceToAddBase"> The chance To Add Base. </param>
 /// <param name="chanceToAddGoldBase"> The chance To Add Gold Base. </param>
 /// <param name="chanceToAddXelNagaTower"> The chance To Add Xel'Naga Tower. </param>
 /// <param name="chanceToAddDestructibleRocks"> The chance To Add Destructible Rocks. </param>
 /// <param name="chanceToAddNewElement"> The chance that an element will be added to a solution during mutation. </param>
 /// <param name="chanceToRemoveElement"> The chance that an element will be removed from a solution during mutation. </param>
 /// <param name="maximumDisplacement"> The maximum Displacement. </param>
 /// <param name="displacementAmountPerStep"> The displacement Amount Per Step. </param>
 /// <param name="tooFewElementsPenalty"> The element Not Placed Penalty. </param>
 /// <param name="tooManyElementsPenalty"> The too Many Elements Penalty. </param>
 /// <param name="noPathBetweenStartBasesPenalty"> The penalty to apply to map phenotypes that do not have a path between starting bases. </param>
 /// <param name="notPlacedPenalty"> The amount to add to the distance when a map point was not placed during conversion.  </param>
 /// <param name="notPlacedPenaltyModifier"> The amount to modify the distance of angle/distance when a map point was not placed during conversion. </param>
 /// <param name="minimumStartBaseDistance"> The minimum Start Base Distance. </param>
 /// <param name="maximumStartBaseDistance"> The maximum Start Base Distance. </param>
 /// <param name="maximumDegree"> The maximum Degree. </param>
 /// <param name="minimumDegree"> The minimum Degree. </param>
 /// <param name="maximumDistance"> The maximum Distance. </param>
 /// <param name="minimumDistance"> The minimum Distance. </param>
 /// <param name="maximumDistanceModifier"> The maximum Distance Modifier. </param>
 /// <param name="minimumDistanceModifier"> The minimum Distance Modifier. </param>
 /// <param name="maximumDegreeModifier"> The maximum Degree Modifier. </param>
 /// <param name="minimumDegreeModifier"> The minimum Degree Modifier. </param>
 /// <param name="minimumNumberOfBases"> The minimum Number Of Bases. </param>
 /// <param name="maximumNumberOfBases"> The maximum Number Of Bases. </param>
 /// <param name="minimumNumberOfRamps"> The minimum Number Of Ramps. </param>
 /// <param name="maximumNumberOfRamps"> The maximum Number Of Ramps. </param>
 /// <param name="minimumNumberOfDestructibleRocks"> The minimum Number Of Destructible Rocks. </param>
 /// <param name="maximumNumberOfDestructibleRocks"> The maximum Number Of Destructible Rocks. </param>
 /// <param name="minimumNumberOfXelNagaTowers"> The minimum Number Of Xel'Naga Towers. </param>
 /// <param name="maximumNumberOfXelNagaTowers"> The maximum Number Of Xel'Naga Towers. </param>
 public MapSearchOptions(
     MapPhenotype mp,
     Enums.MapFunction mapCompletion       = Enums.MapFunction.Turn,
     double chanceToAddBase                = 0.15,
     double chanceToAddGoldBase            = 0.05,
     double chanceToAddXelNagaTower        = 0.05,
     double chanceToAddDestructibleRocks   = 0.45,
     double chanceToAddNewElement          = 0.3,
     double chanceToRemoveElement          = 0.3,
     int maximumDisplacement               = 10,
     int displacementAmountPerStep         = 1,
     double tooFewElementsPenalty          = 5,
     double tooManyElementsPenalty         = 5,
     double noPathBetweenStartBasesPenalty = 100,
     double notPlacedPenalty               = 10,
     double notPlacedPenaltyModifier       = 1.5,
     double minimumStartBaseDistance       = 0.4,
     double maximumStartBaseDistance       = 0.9,
     double maximumDegree                 = 180,
     double minimumDegree                 = 0,
     double maximumDistance               = 1.0,
     double minimumDistance               = 0.15,
     double maximumDistanceModifier       = 0.1,
     double minimumDistanceModifier       = 0.01,
     double maximumDegreeModifier         = 20,
     double minimumDegreeModifier         = 1,
     int minimumNumberOfBases             = 1,
     int maximumNumberOfBases             = 5,
     int minimumNumberOfRamps             = 6,
     int maximumNumberOfRamps             = 18,
     int minimumNumberOfDestructibleRocks = 4,
     int maximumNumberOfDestructibleRocks = 8,
     int minimumNumberOfXelNagaTowers     = 1,
     int maximumNumberOfXelNagaTowers     = 1)
 {
     this.ChanceToAddBase                = chanceToAddBase;
     this.ChanceToAddXelNagaTower        = chanceToAddXelNagaTower;
     this.ChanceToAddDestructibleRocks   = chanceToAddDestructibleRocks;
     this.ChanceToAddGoldBase            = chanceToAddGoldBase;
     this.ChanceToRemoveElement          = chanceToRemoveElement;
     this.ChanceToAddNewElement          = chanceToAddNewElement;
     this.MaximumStartBaseDistance       = maximumStartBaseDistance;
     this.MinimumStartBaseDistance       = minimumStartBaseDistance;
     this.TooManyElementsPenalty         = tooManyElementsPenalty;
     this.TooFewElementsPenalty          = tooFewElementsPenalty;
     this.DisplacementAmountPerStep      = displacementAmountPerStep;
     this.MaximumDisplacement            = maximumDisplacement;
     this.NoPathBetweenStartBasesPenalty = noPathBetweenStartBasesPenalty;
     this.MapCompletion = mapCompletion;
     this.MaximumNumberOfXelNagaTowers     = maximumNumberOfXelNagaTowers;
     this.MinimumNumberOfXelNagaTowers     = minimumNumberOfXelNagaTowers;
     this.MaximumNumberOfDestructibleRocks = maximumNumberOfDestructibleRocks;
     this.MinimumNumberOfDestructibleRocks = minimumNumberOfDestructibleRocks;
     this.MaximumNumberOfRamps             = maximumNumberOfRamps;
     this.MinimumNumberOfRamps             = minimumNumberOfRamps;
     this.MaximumNumberOfBases             = maximumNumberOfBases;
     this.MinimumNumberOfBases             = minimumNumberOfBases;
     this.MinimumDegreeModifier            = minimumDegreeModifier;
     this.MaximumDegreeModifier            = maximumDegreeModifier;
     this.MinimumDistanceModifier          = minimumDistanceModifier;
     this.MaximumDistanceModifier          = maximumDistanceModifier;
     this.MinimumDistance          = minimumDistance;
     this.MaximumDistance          = maximumDistance;
     this.MinimumDegree            = minimumDegree;
     this.MaximumDegree            = maximumDegree;
     this.NotPlacedPenalty         = notPlacedPenalty;
     this.NotPlacedPenaltyModifier = notPlacedPenaltyModifier;
     this.Map = mp;
 }
Esempio n. 6
0
        /// <summary>
        /// Creates base maps using a cellular automaton with the given settings.
        /// </summary>
        /// <param name="mapSize"> The height and width of the base maps. </param>
        /// <param name="oddsOfHeight"> The chance of height1 happening. </param>
        /// <param name="oddsOfHeight2"> The chance of height2 happening.</param>
        /// <param name="maxRangeToGroupPoints"> The max range to the group points. </param>
        /// <param name="groupPoints"> The number of points where terrain should be grouped during the initial seeding. </param>
        /// <param name="generateHeight2"> Determines if the cellular automata should generate height2 or not. </param>
        /// <param name="caRandomSeeds"> The random seeds to use for the CA's random generator. </param>
        /// <param name="caRuleset"> The ruleset to use by the CA. If left as null, the default ruleset is used. </param>
        /// <param name="sections"> The number of impassable terrain sections. </param>
        /// <param name="maxLength"> The max length of impassable terrain sections. </param>
        /// <param name="placementIntervals"> The interval at which areas are placed in the impassable terrain section. </param>
        /// <param name="maxPathNoiseDisplacement"> The max displacement for an area in the impassable terrain.</param>
        /// <param name="maxWidth"> The max width of a point. </param>
        /// <param name="caGenerations"> The number of generations run by the CA. </param>
        /// <param name="generateHeight2ThroughRules"> Determines if height2 should be generated through rules or not.</param>
        /// <param name="smoothingNormalNeighbourhood"> If the number of neighbours in the normal Moore neighbourhood is less than or equal to this number, smoothing happens. </param>
        /// <param name="smoothingExtNeighbourhood"> If the number of neighbours in the extended Moore neighbourhood is less than or equal to this number, smoothing happens. </param>
        /// <param name="smoothingGenerations"> The number of smoothing generations run. </param>
        /// <param name="smoothingRuleSet"> The ruleset used for smoothing. If left as null, the default smoothing ruleset will be used. </param>
        /// <param name="fileToWriteTo"> The file to write the timings to. </param>
        /// <param name="baseMapFolder"> The folder to print the base maps to in "Images/Finished Maps". </param>
        /// <returns> A list of base maps. </returns>
        public static List <MapPhenotype> GetBaseMaps(
            int mapSize                      = 128,
            double oddsOfHeight              = 0.4,
            double oddsOfHeight2             = 0.2,
            int maxRangeToGroupPoints        = 15,
            int groupPoints                  = 3,
            bool generateHeight2             = true,
            List <int> caRandomSeeds         = null,
            List <Rule> caRuleset            = null,
            int sections                     = 4,
            int maxLength                    = 50,
            double placementIntervals        = 0.1,
            int maxPathNoiseDisplacement     = 3,
            int maxWidth                     = 4,
            int caGenerations                = 10,
            bool generateHeight2ThroughRules = true,
            int smoothingNormalNeighbourhood = 2,
            int smoothingExtNeighbourhood    = 6,
            int smoothingGenerations         = 10,
            List <Rule> smoothingRuleSet     = null,
            string fileToWriteTo             = "BaseMapGeneration.txt",
            string baseMapFolder             = "BaseMaps")
        {
            var stringToWrite = new StringBuilder();

            var baseMaps = new List <MapPhenotype>();

            CellularAutomata ca;
            var sw = new Stopwatch();

            sw.Start();

            if (caRandomSeeds == null || caRandomSeeds.Count == 0)
            {
                ca = new CellularAutomata(mapSize, mapSize, Enums.Half.Top, oddsOfHeight, oddsOfHeight2, maxRangeToGroupPoints, groupPoints, generateHeight2);
                if (caRuleset != null)
                {
                    ca.SetRuleset(caRuleset);
                }

                ca.CreateImpassableTerrain(sections, maxLength, placementIntervals, maxPathNoiseDisplacement, maxWidth);

                ca.RunGenerations(caGenerations, generateHeight2ThroughRules);
                var map = new MapPhenotype(ca.Map, new Enums.Item[mapSize, mapSize]);
                map.SmoothTerrain(smoothingNormalNeighbourhood, smoothingExtNeighbourhood, smoothingGenerations, smoothingRuleSet);
                map.PlaceCliffs();
                map.SmoothCliffs();
                map.UpdateCliffPositions(Enums.Half.Top);
                baseMaps.Add(map);

                stringToWrite.AppendLine(string.Format("It took {0} ms to generate the base map.", sw.ElapsedMilliseconds));
            }
            else
            {
                var i = 0;
                foreach (var seed in caRandomSeeds)
                {
                    sw.Restart();

                    var random = new Random(seed);
                    ca = new CellularAutomata(mapSize, mapSize, Enums.Half.Top, oddsOfHeight, oddsOfHeight2, maxRangeToGroupPoints, groupPoints, generateHeight2, random);
                    if (caRuleset != null)
                    {
                        ca.SetRuleset(caRuleset);
                    }

                    ca.CreateImpassableTerrain(sections, maxLength, placementIntervals, maxPathNoiseDisplacement, maxWidth);

                    ca.RunGenerations(caGenerations, generateHeight2ThroughRules);

                    var map = new MapPhenotype(ca.Map, new Enums.Item[mapSize, mapSize]);
                    map.SmoothTerrain(smoothingNormalNeighbourhood, smoothingExtNeighbourhood, smoothingGenerations, smoothingRuleSet, random);
                    map.PlaceCliffs();
                    map.SmoothCliffs();
                    map.UpdateCliffPositions(Enums.Half.Top);
                    baseMaps.Add(map);

                    stringToWrite.AppendLine(string.Format("It took {0} ms to generate base map number {1}.", sw.ElapsedMilliseconds, i));
                    i++;
                }
            }

            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, baseMapFolder);

            return(baseMaps);
        }
Esempio n. 7
0
        /// <summary>
        /// Runs standard evolution and/or MOEA seeded with maps found by the constrained novelty search.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="noveltySearchOptions"> The novelty search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfNoveltyGenerations"> The number of generations to run for the novelty search. </param>
        /// <param name="numberOfEvolutionGenerations"> The number of generations to run for the standard evolution. </param>
        /// <param name="numberOfMOEAGenerations"> The number of generations to run for the MOEA. </param>
        /// <param name="evolutionPopulationSize"> The population size of the standard evolution. </param>
        /// <param name="numberOfParents"> The number of parents for the standard evolution. </param>
        /// <param name="numberOfChildren"> The number of children spawned per generation in the standard evolution. </param>
        /// <param name="evolutionMutationChance"> The chance of mutation happening during evolution. </param>
        /// <param name="moeaPopulationSize"> The population size of the MOEA. </param>
        /// <param name="moeaMutationChance"> The chance of mutation happening in the MOEA. </param>
        /// <param name="selectionStrategy"> The selection strategy used in the standard evolution. </param>
        /// <param name="parentSelectionStrategy"> The parent selection strategy used in the standard evolution. </param>
        /// <param name="populationStrategy"> The population strategy used in the standard evolution. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="selectHighestFitness"> Determines if the maps for seeding are chosen by highest fitness or highest novelty. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        /// <param name="runEvo"> Determines if the standard evolution should be run. </param>
        /// <param name="runMOEA"> Determines if the MOEA should be run. </param>
        public static void RunEvolutionWithNoveltyAsBase(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions         = null,
            NoveltySearchOptions noveltySearchOptions = null,
            MapFitnessOptions mapFitnessOptions       = null,
            int numberOfNoveltyGenerations            = 10,
            int numberOfEvolutionGenerations          = 10,
            int numberOfMOEAGenerations                     = 10,
            int evolutionPopulationSize                     = 20,
            int numberOfParents                             = 6,
            int numberOfChildren                            = 16,
            double evolutionMutationChance                  = 0.3,
            int moeaPopulationSize                          = 25,
            double moeaMutationChance                       = 0.3,
            Enums.SelectionStrategy selectionStrategy       = Enums.SelectionStrategy.ChanceBased,
            Enums.SelectionStrategy parentSelectionStrategy = Enums.SelectionStrategy.ChanceBased,
            Enums.PopulationStrategy populationStrategy     = Enums.PopulationStrategy.Mutation,
            string folderName                 = "MapNoveltyEvolution",
            string fileToWriteTo              = "NoveltyEvolutionHighestFitnessSearchGenerationTimes.txt",
            bool selectHighestFitness         = true,
            double lowestFitnessLevelForPrint = double.MinValue,
            bool runEvo  = true,
            bool runMOEA = true)
        {
            var stringToWrite  = new StringBuilder();
            var mso            = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo            = mapFitnessOptions ?? new MapFitnessOptions();
            var nso            = noveltySearchOptions ?? new NoveltySearchOptions();
            var listOfArchives = new List <List <Solution> >();

            // Novelty search
            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing novelty search on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var searcher = new MapSearcher(r, mso, nso);

                searcher.RunGenerations(numberOfNoveltyGenerations, stringToWrite);

                listOfArchives.Add(searcher.Archive.Archive);

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform novelty search on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                baseMapCounter++;
            }

            baseMapCounter = 0;

            sw.Restart();
            var solutions = new List <List <EvolvableMap> >();

            if (selectHighestFitness)
            {
                stringToWrite.AppendLine(string.Format("Sorting initial population based by highest fitness."));
                foreach (var map in maps)
                {
                    var evolvableMaps = new List <EvolvableMap>();
                    var archive       = listOfArchives[baseMapCounter];

                    foreach (var solution in archive)
                    {
                        var ms = (MapSolution)solution;
                        mso = new MapSearchOptions(map, mso);
                        var evolvableMap = new EvolvableMap(mso, evolutionMutationChance, r, mfo, ms.MapPoints);
                        evolvableMap.CalculateFitness();
                        evolvableMaps.Add(evolvableMap);
                    }

                    solutions.Add(evolvableMaps.OrderByDescending(s => s.Fitness).ToList());

                    baseMapCounter++;
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to find maps with the highest fitness.", sw.ElapsedMilliseconds));
                sw.Restart();
            }
            else
            {
                stringToWrite.AppendLine(string.Format("Sorting initial population based by highest novelty."));
                foreach (var map in maps)
                {
                    var evolvableMaps = new List <EvolvableMap>();
                    var archive       = listOfArchives[baseMapCounter];

                    var tempArchive = archive.OrderByDescending(s => s.Novelty);

                    foreach (var solution in tempArchive)
                    {
                        var ms = (MapSolution)solution;
                        mso = new MapSearchOptions(map, mso);
                        var evolvableMap = new EvolvableMap(mso, evolutionMutationChance, r, mfo, ms.MapPoints);
                        evolvableMap.CalculateFitness();
                        evolvableMaps.Add(evolvableMap);
                    }

                    solutions.Add(evolvableMaps);

                    baseMapCounter++;
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to find maps with the highest novelty.", sw.ElapsedMilliseconds));
                sw.Restart();
            }

            // Evolution
            if (runEvo)
            {
                sw.Restart();
                var bestMaps = new List <EvolvableMap>();
                baseMapCounter = 0;
                foreach (var map in maps)
                {
                    sw.Restart();
                    stringToWrite.AppendLine(string.Format("Performing evolution on base map number {0}.", baseMapCounter));
                    mso = new MapSearchOptions(map, mso);
                    var evolver = new Evolver <EvolvableMap>(
                        numberOfEvolutionGenerations,
                        evolutionPopulationSize,
                        numberOfParents,
                        numberOfChildren,
                        evolutionMutationChance,
                        r,
                        new object[] { mso, evolutionMutationChance, r, mfo })
                    {
                        PopulationSelectionStrategy = selectionStrategy,
                        ParentSelectionStrategy     = parentSelectionStrategy,
                        PopulationStrategy          = populationStrategy
                    };

                    evolver.Initialize(solutions[baseMapCounter].Take(evolutionPopulationSize), stringToWrite);
                    evolver.Evolve(stringToWrite);
                    var variationValue = 0;

                    foreach (var individual in evolver.Population)
                    {
                        variationValue++;
                        if (individual.Fitness >= lowestFitnessLevelForPrint)
                        {
                            individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Evo_Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                        }
                    }

                    stringToWrite.AppendLine(string.Format("It took {0} ms to perform evolution on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                    stringToWrite.AppendLine();

                    bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                    MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Evo_Base Map {0} NoveltyMap", baseMapCounter), folderName);

                    baseMapCounter++;
                }

                MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format("Evo_Best Maps NoveltyMap"), folderName);
            }

            // MOEA
            if (runMOEA)
            {
                baseMapCounter = 0;
                var bestMaps = new List <EvolvableMap>();
                foreach (var map in maps)
                {
                    sw.Restart();
                    stringToWrite.AppendLine(string.Format("Performing multi objective evolution for base map number {0}", baseMapCounter));

                    var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                    var items        = map.MapItems.Clone() as Enums.Item[, ];
                    var baseMap      = new MapPhenotype(heightLevels, items);
                    baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Mirror);
                    baseMap.SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                    mso = new MapSearchOptions(map, mso);
                    var evolver = new MultiObjectiveEvolver(
                        numberOfMOEAGenerations,
                        moeaPopulationSize,
                        moeaMutationChance,
                        r,
                        mso,
                        mfo);

                    evolver.RunEvolution(stringToWrite, solutions[baseMapCounter].Take(moeaPopulationSize));

                    var variationValue = 0;

                    foreach (var individual in evolver.Population)
                    {
                        variationValue++;
                        if (individual.Fitness >= lowestFitnessLevelForPrint)
                        {
                            individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("MOEA_Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                        }
                    }

                    stringToWrite.AppendLine(string.Format("It took {0} ms to perform multi objective evolution on base map number {1}", sw.ElapsedMilliseconds, baseMapCounter));
                    stringToWrite.AppendLine();

                    bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                    MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("MOEA_Base Map {0} NoveltyMap", baseMapCounter), folderName);

                    baseMapCounter++;
                }

                MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format("MOEA_Best Maps NoveltyMap"), folderName);
            }

            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
Esempio n. 8
0
        /// <summary>
        /// Runs novelty search on a given set of maps with the given settings.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="noveltySearchOptions"> The novelty search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunNoveltySearch(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions         = null,
            NoveltySearchOptions noveltySearchOptions = null,
            MapFitnessOptions mapFitnessOptions       = null,
            int numberOfGenerations           = 10,
            string folderName                 = "MapNovelty",
            string fileToWriteTo              = "NoveltySearchGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var stringToWrite = new StringBuilder();

            var mso = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo = mapFitnessOptions ?? new MapFitnessOptions();
            var nso = noveltySearchOptions ?? new NoveltySearchOptions();

            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing novelty search on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var searcher = new MapSearcher(r, mso, nso);

                searcher.RunGenerations(numberOfGenerations, stringToWrite);

                var archiveMaps    = new List <MapPhenotype>();
                var variationValue = 0;
                foreach (var solution in searcher.Archive.Archive)
                {
                    var individual = (MapSolution)solution;
                    variationValue++;
                    var fitness = new MapFitness(individual.ConvertedPhenotype, mfo).CalculateFitness();
                    if (fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, fitness), folderName, false);
                    }
                    else
                    {
                        Console.WriteLine("fitness too low: " + fitness);
                    }

                    archiveMaps.Add(individual.ConvertedPhenotype);
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform novelty search on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                MapHelper.SaveGreyscaleNoveltyMap(archiveMaps, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);

                baseMapCounter++;
            }

            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
Esempio n. 9
0
        /// <summary>
        /// Runs MOEA on a set of maps.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="populationSize"> The population size. </param>
        /// <param name="mutationChance"> The chance of mutation happening. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunMultiobjectiveEvolution(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions   = null,
            MapFitnessOptions mapFitnessOptions = null,
            int numberOfGenerations             = 10,
            int populationSize                = 25,
            double mutationChance             = 0.3,
            string folderName                 = "MapMultiObjectiveEvolution",
            string fileToWriteTo              = "MultiObjectiveEvolutionGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var sb = new StringBuilder();
            var sw = new Stopwatch();

            var mso            = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo            = mapFitnessOptions ?? new MapFitnessOptions();
            var bestMaps       = new List <EvolvableMap>();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                sb.AppendLine(string.Format("Starting evolution for base map number {0}", baseMapCounter));

                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var evolver = new MultiObjectiveEvolver(
                    numberOfGenerations,
                    populationSize,
                    mutationChance,
                    r,
                    mso,
                    mfo);

                var bestMap = evolver.RunEvolution(sb);

                var variationValue = 0;

                foreach (var individual in evolver.Population)
                {
                    variationValue++;
                    if (individual.Fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                    }
                }

                sb.AppendLine(string.Format("Evolution for base map number {0} took {1} ms", baseMapCounter, sw.ElapsedMilliseconds));
                sb.AppendLine();

                bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);
                Console.WriteLine("The map fitness values of base map {0} were: {1}", baseMapCounter, bestMap.MapFitnessValues);

                baseMapCounter++;
            }

            MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format(" Best Maps NoveltyMap"), folderName);
            WriteToTextFile(sb.ToString(), fileToWriteTo, folderName);
        }
Esempio n. 10
0
        /// <summary>
        /// Runs evolution with the given settings.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="populationSize"> The population size of the evolution. </param>
        /// <param name="numberOfParents"> The number of parents used in the evolution. </param>
        /// <param name="numberOfChildren"> The number of children spawned per generation. </param>
        /// <param name="mutationChance"> The chance of mutation happening. </param>
        /// <param name="selectionStrategy"> The selection strategy. </param>
        /// <param name="parentSelectionStrategy"> The parent selection strategy. </param>
        /// <param name="populationStrategy"> The population strategy. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunEvolution(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions   = null,
            MapFitnessOptions mapFitnessOptions = null,
            int numberOfGenerations             = 10,
            int populationSize    = 20,
            int numberOfParents   = 6,
            int numberOfChildren  = 16,
            double mutationChance = 0.3,
            Enums.SelectionStrategy selectionStrategy       = Enums.SelectionStrategy.ChanceBased,
            Enums.SelectionStrategy parentSelectionStrategy = Enums.SelectionStrategy.ChanceBased,
            Enums.PopulationStrategy populationStrategy     = Enums.PopulationStrategy.Mutation,
            string folderName    = "MapEvolution",
            string fileToWriteTo = "EvolutionGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var stringToWrite = new StringBuilder();
            var mso           = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo           = mapFitnessOptions ?? new MapFitnessOptions();
            var bestMaps      = new List <EvolvableMap>();

            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing evolution on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var evolver = new Evolver <EvolvableMap>(
                    numberOfGenerations,
                    populationSize,
                    numberOfParents,
                    numberOfChildren,
                    mutationChance,
                    r,
                    new object[] { mso, mutationChance, r, mfo })
                {
                    PopulationSelectionStrategy = selectionStrategy,
                    ParentSelectionStrategy     = parentSelectionStrategy,
                    PopulationStrategy          = populationStrategy
                };

                evolver.Initialize(stringToWrite);
                var bestMap        = evolver.Evolve(stringToWrite);
                var variationValue = 0;

                foreach (var individual in evolver.Population)
                {
                    variationValue++;
                    if (individual.Fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                    }
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform evolution on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);

                Console.WriteLine("The map fitness values of base map {0} were: {1}", baseMapCounter, ((EvolvableMap)bestMap).MapFitnessValues);

                baseMapCounter++;
            }

            MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format(" Best Maps NoveltyMap"), folderName);
            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
Esempio n. 11
0
        /// <summary>
        /// Converts this individual onto a specific map.
        /// </summary>
        /// <param name="map"> The map to convert this individual onto. </param>
        /// <returns> The <see cref="MapPhenotype"/> that corresponds to this individual.</returns>
        public MapPhenotype ConvertToPhenotype(MapPhenotype map)
        {
            map = MapConversionHelper.ConvertToPhenotype(this.MapPoints, new MapSearchOptions(map, this.MapSearchOptions), this.Random);

            return(map);
        }