private void DoMapping()
        {
            var graph         = levelDescription.GetGraph();
            var stageOneGraph = levelDescription.GetGraphWithoutCorridors();

            foreach (var vertex in graph.Vertices)
            {
                var roomNode = CreateRoomNode(vertex);

                // Create vertices mapping
                mappedGraph.AddVertex(roomNode);

                // Store room description
                roomDescriptions[roomNode.Id] = levelDescription.GetRoomDescription(vertex);
            }

            // Handle main graph edges
            foreach (var edge in graph.Edges)
            {
                mappedGraph.AddEdge(GetRoomNode(edge.From), GetRoomNode(edge.To));
            }

            // Handle stage one graph vertices
            foreach (var vertex in stageOneGraph.Vertices)
            {
                mappedStageOneGraph.AddVertex(GetRoomNode(vertex));
            }

            // Handle stage one graph edges
            foreach (var edge in stageOneGraph.Edges)
            {
                mappedStageOneGraph.AddEdge(GetRoomNode(edge.From), GetRoomNode(edge.To));
            }
        }
        /// <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);
        }
Esempio n. 3
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);
        }
Esempio n. 4
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);
        }
        /// <inheritdoc />
        public virtual void PerturbPosition(TLayout layout, IList <TNode> chain, bool updateLayout)
        {
            // TODO: check what would happen if only invalid nodes could be perturbed
            var canBePerturbed = chain
                                 .Where(x => !LevelDescription.GetRoomDescription(x).IsCorridor) // TODO: handle
                                 .ToList();

            if (canBePerturbed.Count == 0)
            {
                return;
            }

            PerturbPosition(layout, canBePerturbed.GetRandom(Random), updateLayout);
        }
        // TODO: remove when possible
        public Dictionary <Tuple <TNode, TNode>, IRoomDescription> GetNodesToCorridorMapping <TNode>(ILevelDescription <TNode> mapDescription)
        {
            var mapping = new Dictionary <Tuple <TNode, TNode>, IRoomDescription>();

            var graph = mapDescription.GetGraph();

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

                if (roomDescription.IsCorridor)
                {
                    var neighbors = graph.GetNeighbours(room).ToList();
                    mapping.Add(new Tuple <TNode, TNode>(neighbors[0], neighbors[1]), roomDescription);
                    mapping.Add(new Tuple <TNode, TNode>(neighbors[1], neighbors[0]), roomDescription);
                }
            }

            return(mapping);
        }
Esempio n. 7
0
        /// <inheritdoc />
        public List <Chain <TNode> > GetChains(IGraph <TNode> graph)
        {
            // Get all the faces from the stage one graph
            var stageOneGraph = mapDescription.GetGraphWithoutCorridors();
            var faces         = decomposition.GetChains(stageOneGraph);

            var usedVertices         = new HashSet <TNode>();
            var notUsedStageTwoRooms = graph.Vertices.Where(x => mapDescription.GetRoomDescription(x).IsCorridor).ToList();

            // Iterate through all the faces, marking all the seen vertices
            // As soon as all the neighbors of a stage two room are used, add the stage two room to the current face
            foreach (var face in faces)
            {
                // TODO: weird ForEach
                face.Nodes.ToList().ForEach(x => usedVertices.Add(x));

                foreach (var stageTwoRoom in notUsedStageTwoRooms.ToList())
                {
                    var neighbors = graph.GetNeighbours(stageTwoRoom).ToList();

                    if (neighbors.TrueForAll(x => usedVertices.Contains(x)))
                    {
                        notUsedStageTwoRooms.Remove(stageTwoRoom);
                        face.Nodes.Add(stageTwoRoom);
                    }
                }
            }

            // It must not happen that a stage two room is not in the decomposition
            if (notUsedStageTwoRooms.Count != 0)
            {
                throw new ArgumentException();
            }

            return(faces);
        }