public TouchingConstraints(IMapDescription <TNode> mapDescription, IPolygonOverlap <TShapeContainer> polygonOverlap) { this.mapDescription = mapDescription; this.polygonOverlap = polygonOverlap; stageOneGraph = mapDescription.GetStageOneGraph(); graph = mapDescription.GetGraph(); }
private void DoMapping() { var graph = mapDescription.GetGraph(); var stageOneGraph = mapDescription.GetStageOneGraph(); foreach (var vertex in graph.Vertices) { // Create vertices mapping nodeToIntMapping.Add(vertex, nodeToIntMapping.Count); mappedGraph.AddVertex(nodeToIntMapping[vertex]); // Store room description roomDescriptions[nodeToIntMapping[vertex]] = mapDescription.GetRoomDescription(vertex); } // Handle main graph edges foreach (var edge in graph.Edges) { mappedGraph.AddEdge(nodeToIntMapping[edge.From], nodeToIntMapping[edge.To]); } // Handle stage one graph vertices foreach (var vertex in stageOneGraph.Vertices) { mappedStageOneGraph.AddVertex(nodeToIntMapping[vertex]); } // Handle stage one graph edges foreach (var edge in stageOneGraph.Edges) { mappedStageOneGraph.AddEdge(nodeToIntMapping[edge.From], nodeToIntMapping[edge.To]); } }
private IMapDescription <int> GetIntMapDescription(IMapDescription <Room> mapDescription) { var newMapDescription = new MapDescription <int>(); var mapping = mapDescription.GetGraph().Vertices.CreateIntMapping(); foreach (var vertex in mapDescription.GetGraph().Vertices) { newMapDescription.AddRoom(mapping[vertex], mapDescription.GetRoomDescription(vertex)); } foreach (var edge in mapDescription.GetGraph().Edges) { newMapDescription.AddConnection(mapping[edge.From], mapping[edge.To]); } return(newMapDescription); }
public CorridorConstraints(IMapDescription <TNode> mapDescription, float averageSize, IConfigurationSpaces <TNode, TShapeContainer, TConfiguration, ConfigurationSpace> configurationSpaces) { this.mapDescription = mapDescription; this.energySigma = 10 * averageSize; // TODO: should it be like this? this.configurationSpaces = configurationSpaces; stageOneGraph = mapDescription.GetStageOneGraph(); graph = mapDescription.GetGraph(); }
public double ComputeAverageRoomTemplatesEntropy <TNode>(IMapDescription <TNode> mapDescription, List <MapLayout <TNode> > layouts, bool normalize = true) { return(mapDescription .GetGraph() .Vertices .Where(x => mapDescription.GetRoomDescription(x).RoomTemplates.Count > 1) .Select(x => ComputeRoomTemplatesEntropy(mapDescription, layouts, x, normalize)) .Average()); }
private IMutation <TConfiguration> GetMutation(int priority, int maxTreeSize, bool mergeSmallChains, bool startTreeWithMultipleVertices, TreeComponentStrategy treeComponentStrategy) { var configuration = new ChainDecompositionConfiguration() { MaxTreeSize = maxTreeSize, MergeSmallChains = mergeSmallChains, StartTreeWithMultipleVertices = startTreeWithMultipleVertices, TreeComponentStrategy = treeComponentStrategy, }; var chains = new TwoStageChainDecomposition <TNode>(mapDescription, new BreadthFirstChainDecomposition <TNode>(configuration)) .GetChains(mapDescription.GetGraph()).ToList(); return(new ChainDecompositionMutation <TConfiguration, TNode>(priority, chains, maxTreeSize, mergeSmallChains, startTreeWithMultipleVertices, treeComponentStrategy)); }
public static double GetAverageRoomTemplateSize <TNode>(IMapDescription <TNode> mapDescription) { var roomTemplates = mapDescription .GetGraph() .Vertices .Select(mapDescription.GetRoomDescription) .Where(x => x is BasicRoomDescription) .SelectMany(x => x.RoomTemplates) .Distinct() .ToList(); var averageSize = roomTemplates .Select(x => x.Shape.BoundingRectangle.Width + x.Shape.BoundingRectangle.Height) .Average(); return(averageSize); }
public Dictionary <Tuple <TNode, TNode>, CorridorRoomDescription> GetNodesToCorridorMapping <TNode>(IMapDescription <TNode> mapDescription) { var mapping = new Dictionary <Tuple <TNode, TNode>, CorridorRoomDescription>(); var graph = mapDescription.GetGraph(); foreach (var room in graph.Vertices) { var roomDescription = mapDescription.GetRoomDescription(room); if (roomDescription is CorridorRoomDescription corridorRoomDescription) { var neighbors = graph.GetNeighbours(room).ToList(); mapping.Add(new Tuple <TNode, TNode>(neighbors[0], neighbors[1]), corridorRoomDescription); mapping.Add(new Tuple <TNode, TNode>(neighbors[1], neighbors[0]), corridorRoomDescription); } } return(mapping); }
public static LevelDescriptionGrid2D <TNode> GetLevelDescription <TNode>(this IMapDescription <TNode> mapDescription) { var levelDescription = new LevelDescriptionGrid2D <TNode>(); var graph = mapDescription.GetGraph(); var corridorRoomDescriptions = new Dictionary <IRoomDescription, RoomDescriptionGrid2D>(); var roomTemplateMapping = new Dictionary <RoomTemplate, RoomTemplateGrid2D>(); foreach (var room in graph.Vertices) { var roomDescription = mapDescription.GetRoomDescription(room); if (roomDescription.IsCorridor) { if (corridorRoomDescriptions.TryGetValue(roomDescription, out var cached)) { levelDescription.AddRoom(room, cached); } else { var corridorRoomDescription = new RoomDescriptionGrid2D(true, roomDescription.RoomTemplates.Select(x => GetNewRoomTemplate(x, roomTemplateMapping)).ToList()); corridorRoomDescriptions[roomDescription] = corridorRoomDescription; levelDescription.AddRoom(room, corridorRoomDescription); } } else { levelDescription.AddRoom(room, new RoomDescriptionGrid2D(false, roomDescription.RoomTemplates.Select(x => GetNewRoomTemplate(x, roomTemplateMapping)).ToList())); } } foreach (var edge in graph.Edges) { levelDescription.AddConnection(edge.From, edge.To); } return(levelDescription); }
private void SetupGenerator() { var mapping = mapDescription.GetMapping(); var chainsGeneric = configuration.Chains; if (chainsGeneric == null) { var chainDecomposition = new TwoStageChainDecomposition <TNode>(mapDescriptionOriginal, new BreadthFirstChainDecomposition <TNode>(configuration.ChainDecompositionConfiguration ?? new ChainDecompositionConfiguration())); chainsGeneric = chainDecomposition.GetChains(mapDescriptionOriginal.GetGraph()); } var chains = chainsGeneric .Select(x => new Chain <int>(x.Nodes.Select(y => mapping[y]).ToList(), x.Number)) .ToList(); var generatorPlanner = new GeneratorPlanner <Layout <Configuration <CorridorsData> >, int>(configuration.SimulatedAnnealingMaxBranching); var configurationSpacesGenerator = new ConfigurationSpacesGenerator( new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils()); var configurationSpaces = configurationSpacesGenerator.GetConfigurationSpaces <Configuration <CorridorsData> >(mapDescription); //var corridorConfigurationSpaces = mapDescription.IsWithCorridors ? configurationSpacesGenerator.Generate<TNode, Configuration<CorridorsData>>(mapDescription, mapDescription.CorridorsOffsets) : configurationSpaces; var corridorConfigurationSpaces = configurationSpaces; var averageSize = configurationSpaces.GetAverageSize(); var polygonOverlap = new FastPolygonOverlap(); var stageOneConstraints = new List <INodeConstraint <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData> > { new BasicConstraint <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( new FastPolygonOverlap(), averageSize, configurationSpaces ), new CorridorConstraints <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( mapDescription, averageSize, corridorConfigurationSpaces ), }; if (!configuration.RoomsCanTouch) { stageOneConstraints.Add(new TouchingConstraints <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( mapDescription, polygonOverlap )); } var stageOneConstraintsEvaluator = new ConstraintsEvaluator <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, IntAlias <PolygonGrid2D>, CorridorsData>(stageOneConstraints); //if (mapDescription.IsWithCorridors) //{ // layoutOperations.AddNodeConstraint(new CorridorConstraints<Layout<Configuration<CorridorsData>>, int, Configuration<CorridorsData>, CorridorsData, IntAlias<GridPolygon>>( // mapDescription, // averageSize, // corridorConfigurationSpaces // )); // if (!false) // TODO: // { // var polygonOverlap = new FastPolygonOverlap(); // layoutOperations.AddNodeConstraint(new TouchingConstraints<Layout<Configuration<CorridorsData>>, int, Configuration<CorridorsData>, CorridorsData, IntAlias<GridPolygon>>( // mapDescription, // polygonOverlap // )); // } //} var roomShapesHandler = new RoomShapesHandler <int, Configuration <CorridorsData> >( configurationSpaces, configurationSpaces.GetIntAliasMapping(), mapDescription, configuration.RepeatModeOverride ); var layoutOperations = new LayoutOperations <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, IntAlias <PolygonGrid2D>, CorridorsData>(corridorConfigurationSpaces, configurationSpaces.GetAverageSize(), mapDescription, stageOneConstraintsEvaluator, stageOneConstraintsEvaluator, roomShapesHandler, configuration.ThrowIfRepeatModeNotSatisfied); var initialLayout = new Layout <Configuration <CorridorsData> >(mapDescription.GetGraph()); var layoutConverter = new BasicLayoutConverter <Layout <Configuration <CorridorsData> >, TNode, Configuration <CorridorsData> >(mapDescription, configurationSpaces, configurationSpaces.GetIntAliasMapping()); var layoutEvolver = new PlatformersEvolver <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData> >(layoutOperations); generator = new ChainBasedGenerator <Layout <Configuration <CorridorsData> >, MapLayout <TNode>, int>(initialLayout, generatorPlanner, chains, layoutEvolver, layoutConverter); generator.OnRandomInjected += (random) => { ((IRandomInjectable)configurationSpaces).InjectRandomGenerator(random); ((IRandomInjectable)layoutOperations).InjectRandomGenerator(random); ((IRandomInjectable)layoutEvolver).InjectRandomGenerator(random); ((IRandomInjectable)layoutConverter).InjectRandomGenerator(random); }; generator.OnCancellationTokenInjected += (token) => { ((ICancellable)generatorPlanner).SetCancellationToken(token); ((ICancellable)layoutEvolver).SetCancellationToken(token); }; // layoutEvolver.OnEvent += (sender, args) => OnSimulatedAnnealingEvent?.Invoke(sender, args); layoutEvolver.OnPerturbed += (sender, layout) => OnPerturbed?.Invoke(layoutConverter.Convert(layout, false)); layoutEvolver.OnPerturbed += (sender, layout) => OnPerturbedInternal?.Invoke(layout); layoutEvolver.OnValid += (sender, layout) => OnPartialValid?.Invoke(layoutConverter.Convert(layout, true)); generatorPlanner.OnLayoutGenerated += layout => OnValid?.Invoke(layoutConverter.Convert(layout, true)); }
public MapDescriptionMapping(IMapDescription <TNode> mapDescription) { this.mapDescription = mapDescription; roomDescriptions = new IRoomDescription[mapDescription.GetGraph().VerticesCount]; DoMapping(); }
public ConfigurationSpaces <TConfiguration> GetConfigurationSpaces <TConfiguration>(IMapDescription <int> mapDescription) where TConfiguration : IConfiguration <IntAlias <PolygonGrid2D>, int> { var graph = mapDescription.GetGraph(); var roomDescriptions = graph .Vertices .ToDictionary(x => x, mapDescription.GetRoomDescription); var roomTemplates = roomDescriptions .Values .SelectMany(x => x.RoomTemplates) .Distinct() .ToList(); var roomTemplateInstances = roomTemplates .ToDictionary(x => x, GetRoomTemplateInstances); var roomTemplateInstancesMapping = roomTemplateInstances .SelectMany(x => x.Value) .CreateIntMapping(); var roomTemplateInstancesCount = roomTemplateInstancesMapping.Count; var corridorRoomDescriptionsMapping = roomDescriptions .Values .Where(x => x.GetType() == typeof(CorridorRoomDescription)) .Cast <CorridorRoomDescription>() .Distinct() .CreateIntMapping(); var corridorRoomTemplateInstances = corridorRoomDescriptionsMapping .Keys .ToDictionary( x => x, x => x.RoomTemplates.SelectMany(y => roomTemplateInstances[y]).ToList()); var nodesToCorridorMapping = GetNodesToCorridorMapping(mapDescription) .ToDictionary( x => x.Key, x => corridorRoomDescriptionsMapping[x.Value] + 1 ); var configurationSpaces = new ConfigurationSpaces <TConfiguration>(lineIntersection, roomTemplateInstancesCount, graph.VerticesCount, (configuration1, configuration2) => { if (nodesToCorridorMapping.TryGetValue(new Tuple <int, int>(configuration1.Node, configuration2.Node), out var corridor)) { return(corridor); } return(0); }); // Generate configuration spaces foreach (var shape1 in roomTemplateInstancesMapping.Keys) { foreach (var shape2 in roomTemplateInstancesMapping.Keys) { var configurationSpacesList = new ConfigurationSpace[corridorRoomDescriptionsMapping.Count + 1]; configurationSpacesList[0] = GetConfigurationSpace(shape1, shape2); foreach (var pair in corridorRoomDescriptionsMapping) { var roomDescription = pair.Key; var intAlias = pair.Value; configurationSpacesList[intAlias + 1] = GetConfigurationSpaceOverCorridors(shape1, shape2, corridorRoomTemplateInstances[roomDescription]); } configurationSpaces.AddConfigurationSpace(shape1, shape2, configurationSpacesList.ToArray()); } } foreach (var vertex in graph.Vertices) { var roomDescription = mapDescription.GetRoomDescription(vertex); foreach (var roomTemplate in roomDescription.RoomTemplates) { var instances = roomTemplateInstances[roomTemplate]; foreach (var roomTemplateInstance in instances) { configurationSpaces.AddShapeForNode(vertex, roomTemplateInstance, 1d / instances.Count); } } } return(configurationSpaces); }