Пример #1
0
        public Result Run(LevelDescriptionGrid2D levelDescription)
        {
            var graph        = levelDescription.GetGraph();
            var nonTreeEdges = graph.Edges.Count() - graph.VerticesCount + 1;
            var result       = new Result();

            result.NumberOfCycles = nonTreeEdges;

            if (nonTreeEdges >= 2)
            {
                result.IsPotentialProblem = true;
                var sb = new StringBuilder();

                sb.AppendLine($"It seems like the level graph has at least {nonTreeEdges} cycles.");
                sb.AppendLine($"The larger the number of cycles, the harder it is for the generator to produce a level.");
                sb.AppendLine($"Graphs without cycles are the easiest for the algorithm to generate. It is usually recommended to have at most 2 cycles.");
                sb.AppendLine($"If you want to see whether the number of cycles causes is too high for the generator, try removing some of the cycles and see if/how much the performance changes.");
                sb.AppendLine($"Or if you really want to have cycles in your levels, make sure that your room templates have as many available door positions as possible.");

                result.Summary = sb.ToString();
            }
            else
            {
                result.IsPotentialProblem = false;
            }

            return(result);
        }
        public IGeneratorRunner GetGeneratorRunner(LevelDescriptionGrid2D <TNode> levelDescription)
        {
            if (benchmarkInitialization)
            {
                return(GetGeneratorRunnerWithInit(levelDescription));
            }

            var configuration = this.configuration.SmartClone();

            configuration.RoomsCanTouch = levelDescription.MinimumRoomDistance == 0;

            var mapDescription = levelDescription.GetMapDescription();

            var chainDecompositionOld = new BreadthFirstChainDecompositionOld <TNode>();
            var chainDecomposition    = new TwoStageChainDecomposition <TNode>(mapDescription, chainDecompositionOld);

            configuration.Chains = chainDecomposition.GetChains(levelDescription.GetGraph());
            configuration.SimulatedAnnealingConfiguration = new SimulatedAnnealingConfigurationProvider(new SimulatedAnnealingConfiguration()
            {
                MaxIterationsWithoutSuccess = 10000,
            });

            var layoutDrawer = new SVGLayoutDrawer <TNode>();

            var layoutGenerator = new DungeonGenerator <TNode>(mapDescription, configuration);

            layoutGenerator.InjectRandomGenerator(new Random(0));

            return(new LambdaGeneratorRunner(() =>
            {
                var simulatedAnnealingArgsContainer = new List <SimulatedAnnealingEventArgs>();

                void SimulatedAnnealingEventHandler(object sender, SimulatedAnnealingEventArgs eventArgs)
                {
                    simulatedAnnealingArgsContainer.Add(eventArgs);
                }

                layoutGenerator.OnSimulatedAnnealingEvent += SimulatedAnnealingEventHandler;
                var layout = layoutGenerator.GenerateLayout();
                layoutGenerator.OnSimulatedAnnealingEvent -= SimulatedAnnealingEventHandler;

                var additionalData = new AdditionalRunData <TNode>()
                {
                    SimulatedAnnealingEventArgs = simulatedAnnealingArgsContainer,
                    GeneratedLayoutSvg =
                        layout != null ? layoutDrawer.DrawLayout(layout, 800, forceSquare: true) : null,
                    GeneratedLayout = layout,
                };

                var generatorRun = new GeneratorRun <AdditionalRunData <TNode> >(layout != null, layoutGenerator.TimeTotal,
                                                                                 layoutGenerator.IterationsCount, additionalData);

                return generatorRun;
            }));
        }
Пример #3
0
        private void UpdateInfo()
        {
            descriptionNotChosen.Hide();
            var graph = levelDescription.GetGraph();

            usedDescription.Text              = usingUploaded ? $"Using uploaded map description file." : $"Using map description file from Resources.";
            usedDescriptionRoomsCount.Text    = $"Number of rooms: {graph.VerticesCount}";
            usedDescriptionPassagesCount.Text = $"Number of passages: {graph.Edges.Count()}";

            usedDescriptionInfoPanel.Show();
        }
Пример #4
0
        private void DrawRoomTemplates(RectangleF rect)
        {
            var roomTemplates = levelDescription
                                .GetGraph().Vertices
                                .Select(levelDescription.GetRoomDescription)
                                .Where(x => x.IsCorridor == false)
                                .SelectMany(x => x.RoomTemplates)
                                .Distinct()
                                .ToList();
            var roomTemplatesDrawer = new RoomTemplateDrawerOld <TRoom>();
            var roomTemplatesBitmap = roomTemplatesDrawer.DrawRoomTemplates(roomTemplates, (int)rect.Width, (int)rect.Height, true, 1.5f, 0.2f);

            graphics.DrawImage(roomTemplatesBitmap, rect);
        }
Пример #5
0
        public static IMapDescription <TNode> GetMapDescription <TNode>(this LevelDescriptionGrid2D <TNode> levelDescription)
        {
            var mapDescription = new MapDescription <TNode>();
            var graph          = levelDescription.GetGraph();

            var corridorRoomDescriptions = new Dictionary <RoomDescriptionGrid2D, CorridorRoomDescription>();
            var roomTemplateMapping      = new Dictionary <RoomTemplateGrid2D, RoomTemplate>();

            foreach (var room in graph.Vertices)
            {
                var roomDescription = levelDescription.GetRoomDescription(room);

                if (roomDescription.IsCorridor)
                {
                    if (corridorRoomDescriptions.TryGetValue(roomDescription, out var cached))
                    {
                        mapDescription.AddRoom(room, cached);
                    }
                    else
                    {
                        var corridorRoomDescription = new CorridorRoomDescription(roomDescription.RoomTemplates.Select(x => GetOldRoomTemplate(x, roomTemplateMapping)).ToList());
                        corridorRoomDescriptions[roomDescription] = corridorRoomDescription;
                        mapDescription.AddRoom(room, corridorRoomDescription);
                    }
                }
                else
                {
                    mapDescription.AddRoom(room, new BasicRoomDescription(roomDescription.RoomTemplates.Select(x => GetOldRoomTemplate(x, roomTemplateMapping)).ToList()));
                }
            }

            foreach (var edge in graph.Edges)
            {
                mapDescription.AddConnection(edge.From, edge.To);
            }

            return(mapDescription);
        }
Пример #6
0
        public Result Run(LevelDescriptionGrid2D levelDescription)
        {
            var graph    = levelDescription.GetGraph();
            var vertices = graph.VerticesCount;
            var result   = new Result();

            result.NumberOfRooms = vertices;

            if (vertices > 20)
            {
                result.IsPotentialProblem = true;
                var sb = new StringBuilder();
                sb.AppendLine($"The level graph has quite a lot of rooms ({vertices}).");
                sb.AppendLine($"The higher the number of rooms, the harder it is for the generator to produce a level.");
                sb.AppendLine($"If you want to have a lot of rooms in the level, it is best to limit the number of cycles.");
                result.Summary = sb.ToString();
            }
            else
            {
                result.IsPotentialProblem = false;
            }

            return(result);
        }
Пример #7
0
 /// <summary>
 /// Gets the graph of rooms where also corridors are considered to be rooms.
 /// </summary>
 /// <remarks>
 /// The graph is not updated when new rooms are added to the level description.
 /// Adding rooms to the graph does not update the level description.
 /// This behaviour may change in the future.
 /// </remarks>
 /// <returns></returns>
 public IGraph <RoomBase> GetGraphWithCorridors()
 {
     return(levelDescription.GetGraph());
 }