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; })); }
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(); }
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); }
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); }
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); }
/// <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()); }