/// <summary>
        /// Gets a basic layout generator that should not be used to generated layouts with corridors.
        /// </summary>
        /// <typeparam name="TNode"></typeparam>
        /// <returns></returns>
        public static ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IMapLayout <TNode> > GetDefaultChainBasedGenerator <TNode>()
        {
            var layoutGenerator = new ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IMapLayout <TNode> >();

            var chainDecomposition           = new BreadthFirstChainDecomposition <int>(new GraphDecomposer <int>());
            var configurationSpacesGenerator = new ConfigurationSpacesGenerator(new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils());
            var generatorPlanner             = new BasicGeneratorPlanner <Layout <Configuration <EnergyData>, BasicEnergyData> >();

            layoutGenerator.SetChainDecompositionCreator(mapDescription => chainDecomposition);
            layoutGenerator.SetConfigurationSpacesCreator(mapDescription => configurationSpacesGenerator.Generate <TNode, Configuration <EnergyData> >(mapDescription));
            layoutGenerator.SetInitialLayoutCreator(mapDescription => new Layout <Configuration <EnergyData>, BasicEnergyData>(mapDescription.GetGraph()));
            layoutGenerator.SetGeneratorPlannerCreator(mapDescription => generatorPlanner);
            layoutGenerator.SetLayoutConverterCreator((mapDescription, configurationSpaces) => new BasicLayoutConverter <Layout <Configuration <EnergyData>, BasicEnergyData>, TNode, Configuration <EnergyData> >(mapDescription, configurationSpaces, configurationSpacesGenerator.LastIntAliasMapping));
            layoutGenerator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => new SimulatedAnnealingEvolver <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData> >(layoutOperations));
            layoutGenerator.SetLayoutOperationsCreator((mapDescription, configurationSpaces) =>
            {
                var layoutOperations = new LayoutOperationsWithConstraints <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IntAlias <GridPolygon>, EnergyData, BasicEnergyData>(configurationSpaces, configurationSpaces.GetAverageSize());

                var averageSize = configurationSpaces.GetAverageSize();

                layoutOperations.AddNodeConstraint(new BasicContraint <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, EnergyData, IntAlias <GridPolygon> >(
                                                       new FastPolygonOverlap(),
                                                       averageSize,
                                                       configurationSpaces
                                                       ));

                return(layoutOperations);
            });

            return(layoutGenerator);
        }
        private DungeonGeneratorConfiguration <int> GetChainsConfiguration(NamedMapDescription namedMapDescription)
        {
            var chainDecompositionOld = new BreadthFirstChainDecomposition <int>(new ChainDecompositionConfiguration());
            var chainDecomposition    = new TwoStageChainDecomposition <int>(namedMapDescription.MapDescription, chainDecompositionOld);

            var configuration = GetOldConfiguration(namedMapDescription);

            configuration.Chains = chainDecomposition.GetChains(namedMapDescription.MapDescription.GetGraph());

            return(configuration);
        }
Esempio n. 3
0
        /// <summary>
        /// Gets a generator that can work with corridors.
        /// </summary>
        /// <remarks>
        /// TODO: This is only a temporary solution because we must be able to inject our own corridor nodes creator and this is the easiest way right now.
        /// </remarks>
        /// <param name="offsets"></param>
        /// <param name="canTouch">Whether rooms can touch. Perfomance is decreased when set to false.</param>
        /// <param name="corridorNodesCreator"></param>
        /// <returns></returns>
        public static ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IMapLayout <TNode> > GetChainBasedGeneratorWithCorridors <TNode>(List <int> offsets, bool canTouch = false, ICorridorNodesCreator <TNode> corridorNodesCreator = null)
        {
            var layoutGenerator = new ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IMapLayout <TNode> >();

            var chainDecomposition           = new BreadthFirstChainDecomposition <int>();
            var configurationSpacesGenerator = new ConfigurationSpacesGenerator(new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils());
            var generatorPlanner             = new BasicGeneratorPlanner <Layout <Configuration <CorridorsData>, BasicEnergyData> >();

            layoutGenerator.SetChainDecompositionCreator(mapDescription => new CorridorsChainDecomposition <int>(mapDescription, chainDecomposition));
            layoutGenerator.SetConfigurationSpacesCreator(mapDescription => configurationSpacesGenerator.Generate <TNode, Configuration <CorridorsData> >(mapDescription));
            layoutGenerator.SetInitialLayoutCreator(mapDescription => new Layout <Configuration <CorridorsData>, BasicEnergyData>(mapDescription.GetGraph()));
            layoutGenerator.SetGeneratorPlannerCreator(mapDescription => generatorPlanner);
            layoutGenerator.SetLayoutConverterCreator((mapDescription, configurationSpaces) => new BasicLayoutConverter <Layout <Configuration <CorridorsData>, BasicEnergyData>, TNode, Configuration <CorridorsData> >(mapDescription, configurationSpaces, configurationSpacesGenerator.LastIntAliasMapping, corridorNodesCreator));
            layoutGenerator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => new SimulatedAnnealingEvolver <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData> >(layoutOperations));
            layoutGenerator.SetLayoutOperationsCreator((mapDescription, configurationSpaces) =>
            {
                var corridorConfigurationSpaces = configurationSpacesGenerator.Generate <TNode, Configuration <CorridorsData> >(mapDescription, offsets);
                var layoutOperations            = new LayoutOperationsWithCorridors <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IntAlias <GridPolygon>, CorridorsData, BasicEnergyData>(configurationSpaces, mapDescription, corridorConfigurationSpaces, configurationSpaces.GetAverageSize());
                var polygonOverlap = new FastPolygonOverlap();

                var averageSize = configurationSpaces.GetAverageSize();

                layoutOperations.AddNodeConstraint(new BasicContraint <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >(
                                                       polygonOverlap,
                                                       averageSize,
                                                       configurationSpaces
                                                       ));

                layoutOperations.AddNodeConstraint(new CorridorConstraints <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >(
                                                       mapDescription,
                                                       averageSize,
                                                       corridorConfigurationSpaces
                                                       ));

                if (!canTouch)
                {
                    layoutOperations.AddNodeConstraint(new TouchingConstraints <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >(
                                                           mapDescription,
                                                           polygonOverlap
                                                           ));
                }

                return(layoutOperations);
            });

            return(layoutGenerator);
        }
Esempio n. 4
0
        protected override void Run()
        {
            var graphs = MapDescriptionLoader.GetGraphs();
            var cycleClustersAnalyzer    = new CycleClustersAnalyzer <int>();
            var nodesInsideCycleAnalyzer = new NodesInsideCycleAnalyzer <int>();

            //var benchmarkText =
            //    File.ReadAllText(
            //        @"D:\ProceduralLevelGenerator-data\Random\1583013308_FixedMaxIterationsEvolution_Time_edges_3_3_NewConfigurations - Copy.json");
            var benchmarkResult = JsonConvert.DeserializeObject <BenchmarkScenarioResult>(File.ReadAllText(
                                                                                              @"D:\ProceduralLevelGenerator-data\Random\1588689334_OldAndNew_edges_3_3\1588689334_OldAndNew_edges_3_3_ChainsAndMaxIterationAndTrees.json"));

            var correct = 0;
            var tp      = 0;
            var fp      = 0;
            var fn      = 0;

            var chainDecomposition = new BreadthFirstChainDecomposition <int>(new ChainDecompositionConfiguration()
            {
                // PreferSmallCycles = false,
            });

            for (var i = 0; i < graphs.Count; i++)
            {
                var namedGraph = graphs[i];
                var result     = benchmarkResult.BenchmarkResults[2 * i];

                var maxCyclesInClusterThreshold = 4;
                var nodesInsideThreshold        = 40;

                var clustersReport  = cycleClustersAnalyzer.GetReport(namedGraph.Graph);
                var maxClusterIndex = clustersReport.Clusters.MaxBy(x => x.Nodes.Count);
                var maxClusterSize  = clustersReport.Clusters[maxClusterIndex].Nodes.Count;

                var nodesInsideCycleReport = nodesInsideCycleAnalyzer.GetReport(namedGraph.Graph);

                Console.Write($"{namedGraph.Name.PadRight(15)}");

                Console.Write($"{clustersReport.MaxDensity,4:F}");

                if (clustersReport.MaxCyclesInCluster >= maxCyclesInClusterThreshold)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                }

                Console.Write($"{clustersReport.MaxCyclesInCluster,3}");
                Console.ResetColor();

                Console.Write($"{maxClusterSize,3}");

                if (nodesInsideCycleReport.ProblemsCount >= nodesInsideThreshold)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                }
                Console.Write($"{nodesInsideCycleReport.ProblemsCount,3}");
                Console.ResetColor();

                Console.Write($"{result.Runs.Average(x => x.Time),12:F}");

                var resultNok = result.Runs.Average(x => x.Time) > 5000;
                var reportNok = (clustersReport.MaxCyclesInCluster >= maxCyclesInClusterThreshold) || nodesInsideCycleReport.ProblemsCount >= nodesInsideThreshold;

                if (reportNok && resultNok)
                {
                    tp++;
                }

                if (reportNok && !resultNok)
                {
                    fp++;
                    Console.Write($"{"fp",3}");
                }

                if (!reportNok && resultNok)
                {
                    fn++;
                    Console.Write($"{"fn",3}");
                }
                else
                {
                    Console.Write("   ");
                }

                if (reportNok == resultNok)
                {
                    correct++;
                }

                if (i == 95)
                {
                    var s = 0;
                }
                var chains = chainDecomposition.GetChains(namedGraph.Graph);
                foreach (var chain in chains)
                {
                    Console.Write($" [{string.Join(",", chain.Nodes)}]");
                }

                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine($"Total acc: {(correct / (double) graphs.Count * 100):F}%");
            Console.WriteLine($"Precision: {(tp / (double) (tp + fp) * 100):F}%");
            Console.WriteLine($"Recall: {(tp / (double) (tp + fn) * 100):F}%");
        }
 protected override void CreateConcrete()
 {
     chainDecomposition = new BreadthFirstChainDecomposition <int>();
 }
            protected override void CreateConcrete()
            {
                var graphDecomposer = new GraphDecomposer <int>();

                chainDecomposition = new BreadthFirstChainDecomposition <int>(graphDecomposer);
            }