示例#1
0
        /// <inheritdoc />
        public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData)
        {
            if (mapDescription.GetRoomDescription(node).IsCorridor)
            {
                return(true);
            }

            oldLayout.GetConfiguration(node, out var oldConfiguration);
            var newDistance = oldConfiguration.EnergyData.CorridorConstraintData.CorridorDistance;

            foreach (var vertex in oldLayout.Graph.Vertices)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration))
                {
                    continue;
                }

                newLayout.GetConfiguration(vertex, out var newNodeConfiguration);
                newDistance += newNodeConfiguration.EnergyData.CorridorConstraintData.CorridorDistance - nodeConfiguration.EnergyData.CorridorConstraintData.CorridorDistance;
            }

            var constraintData = new CorridorConstraintData {
                CorridorDistance = newDistance
            };

            energyData.CorridorConstraintData = constraintData;

            return(newDistance == 0);
        }
示例#2
0
        public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData)
        {
            oldLayout.GetConfiguration(node, out var oldConfiguration);
            var newOverlap  = oldConfiguration.EnergyData.BasicConstraintData.Overlap;
            var newDistance = oldConfiguration.EnergyData.BasicConstraintData.MoveDistance;

            foreach (var vertex in oldLayout.Graph.Vertices)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration))
                {
                    continue;
                }

                newLayout.GetConfiguration(vertex, out var newNodeConfiguration);

                newOverlap  += newNodeConfiguration.EnergyData.BasicConstraintData.Overlap - nodeConfiguration.EnergyData.BasicConstraintData.Overlap;
                newDistance += newNodeConfiguration.EnergyData.BasicConstraintData.MoveDistance - nodeConfiguration.EnergyData.BasicConstraintData.MoveDistance;
            }

            var constraintData = energyData.BasicConstraintData;

            constraintData.MoveDistance    = newDistance;
            constraintData.Overlap         = newOverlap;
            energyData.BasicConstraintData = constraintData;

            return(newOverlap == 0 && newDistance == 0);
        }
        /// <inheritdoc />
        public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData)
        {
            if (mapDescription.GetRoomDescription(node).IsCorridor)
            {
                return(true);
            }

            oldLayout.GetConfiguration(node, out var oldConfiguration);
            var wrongDistanceNew = oldConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount;

            foreach (var vertex in oldLayout.Graph.Vertices)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration))
                {
                    continue;
                }

                newLayout.GetConfiguration(vertex, out var newNodeConfiguration);

                wrongDistanceNew += newNodeConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount - nodeConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount;
            }

            var constraintData = new MinimumDistanceConstraintData()
            {
                WrongDistanceCount = wrongDistanceNew
            };

            energyData.MinimumDistanceConstraintData = constraintData;

            return(wrongDistanceNew == 0);
        }
        /// <inheritdoc />
        public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData)
        {
            // TODO: why this?
            if (mapDescription.GetRoomDescription(node).IsCorridor)
            {
                return(true);
            }

            var wrongDistanceCount = 0;

            foreach (var vertex in layout.Graph.Vertices)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!layout.GetConfiguration(vertex, out var c))
                {
                    continue;
                }

                if (mapDescription.GetRoomDescription(vertex).IsCorridor)
                {
                    continue;
                }

                if (AreNeighbours(node, vertex))
                {
                    continue;
                }

                if (!HaveMinimumDistance(configuration, c))
                {
                    wrongDistanceCount++;
                }
            }

            var constraintData = new MinimumDistanceConstraintData()
            {
                WrongDistanceCount = wrongDistanceCount
            };

            energyData.MinimumDistanceConstraintData = constraintData;

            return(wrongDistanceCount == 0);
        }
示例#5
0
        public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData)
        {
            var isCorridor = optimizeCorridors && mapDescription.GetRoomDescription(node).IsCorridor;

            var overlap   = 0;
            var distance  = 0;
            var neighbors = layout.Graph.GetNeighbours(node).ToList();

            foreach (var vertex in layout.Graph.Vertices)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!layout.GetConfiguration(vertex, out var c))
                {
                    continue;
                }

                var area = ComputeOverlap(configuration, c);

                if (area != 0)
                {
                    overlap += area;
                }
                else if (!isCorridor && neighbors.Contains(vertex))
                {
                    if (!configurationSpaces.HaveValidPosition(configuration, c))
                    {
                        // TODO: this is not really accurate when there are more sophisticated door positions (as smaller distance is not always better)
                        distance += ComputeDistance(configuration, c);
                    }
                }
            }

            var constraintData = new BasicConstraintData {
                Overlap = overlap, MoveDistance = distance
            };

            energyData.BasicConstraintData = constraintData;

            return(overlap == 0 && distance == 0);
        }
示例#6
0
        /// <inheritdoc />
        public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData)
        {
            if (mapDescription.GetRoomDescription(node).IsCorridor)
            {
                return(true);
            }

            var distance   = 0;
            var neighbours = graphWithoutCorridors.GetNeighbours(node).ToList();

            foreach (var vertex in neighbours)
            {
                if (vertex.Equals(node))
                {
                    continue;
                }

                if (!layout.GetConfiguration(vertex, out var c))
                {
                    continue;
                }

                // TODO: why wasn't this here?
                if (!AreNeighboursWithoutCorridors(vertex, node))
                {
                    continue;
                }

                if (!configurationSpaces.HaveValidPosition(configuration, c))
                {
                    distance += ComputeDistance(configuration, c);
                }
            }

            var constraintData = new CorridorConstraintData {
                CorridorDistance = distance
            };

            energyData.CorridorConstraintData = constraintData;

            return(distance == 0);
        }
        /// <summary>
        /// Computes updated energy data of the node that was perturbed.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="oldLayout"></param>
        /// <param name="newLayout"></param>
        /// <returns></returns>
        public TEnergyData UpdateNodeEnergy(TNode node, ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout)
        {
            var energyData = new TEnergyData();
            var valid      = true;

            foreach (var constraint in constraints)
            {
                if (!constraint.UpdateEnergyData(oldLayout, newLayout, node, ref energyData))
                {
                    valid = false;
                }
            }

            energyData.IsValid = valid;

            // TODO: weird
            newLayout.GetConfiguration(node, out var configuration);
            energyUpdater.UpdateEnergy(newLayout, configuration, ref energyData);

            return(energyData);
        }
示例#8
0
        /// <inheritdoc />
        public LayoutGrid2D <TNode> Convert(ILayout <RoomNode <TNode>, TConfiguration> layout, bool addDoors)
        {
            var rooms     = new List <LayoutRoomGrid2D <TNode> >();
            var roomsDict = new Dictionary <TNode, LayoutRoomGrid2D <TNode> >();

            foreach (var vertexAlias in layout.Graph.Vertices)
            {
                if (layout.GetConfiguration(vertexAlias, out var configuration))
                {
                    var vertex = vertexAlias.Room;
                    var roomTemplateInstance = configuration.RoomShape;

                    // Make sure that the returned shape has the same position as the original room template shape and is not moved to (0,0)
                    // TODO: maybe make a unit/integration test?
                    var transformation   = roomTemplateInstance.Transformations.GetRandom(Random);
                    var shape            = configuration.RoomShape.RoomShape;
                    var originalShape    = roomTemplateInstance.RoomTemplate.Outline;
                    var transformedShape = originalShape.Transform(transformation);
                    var offset           = transformedShape.BoundingRectangle.A - shape.BoundingRectangle.A;

                    var room = new LayoutRoomGrid2D <TNode>(vertex, transformedShape, configuration.Position - offset, MapDescription.GetRoomDescription(vertexAlias.Room).IsCorridor, roomTemplateInstance.RoomTemplate, MapDescription.GetRoomDescription(vertexAlias.Room), transformation);
                    rooms.Add(room);

                    if (!addDoors)
                    {
                        continue;
                    }

                    var doors = new List <LayoutDoorGrid2D <TNode> >();
                    room.Doors = doors;

                    roomsDict[vertex] = room;
                }
            }

            if (addDoors)
            {
                var generatedDoors = new HashSet <Tuple <TNode, TNode> >();

                foreach (var vertexAlias in layout.Graph.Vertices)
                {
                    var vertex = vertexAlias.Room;

                    if (layout.GetConfiguration(vertexAlias, out var configuration))
                    {
                        var neighbours = layout.Graph.GetNeighbours(vertexAlias);

                        foreach (var neighbourAlias in neighbours)
                        {
                            var neighbour = neighbourAlias.Room;

                            if (layout.GetConfiguration(neighbourAlias, out var neighbourConfiguration) && !generatedDoors.Contains(Tuple.Create(neighbour, vertex)))
                            {
                                var doorChoices  = GetDoors(configuration, neighbourConfiguration);
                                var randomChoice = doorChoices.GetRandom(Random);

                                roomsDict[vertex].Doors.Add(new LayoutDoorGrid2D <TNode>(vertex, neighbour, randomChoice + -1 * roomsDict[vertex].Position));
                                roomsDict[neighbour].Doors.Add(new LayoutDoorGrid2D <TNode>(neighbour, vertex, randomChoice + -1 * roomsDict[neighbour].Position));
                                generatedDoors.Add(Tuple.Create(vertex, neighbour));
                            }
                        }
                    }
                }
            }

            return(new LayoutGrid2D <TNode>(rooms));
        }