Beispiel #1
0
        public void RoomsOnSideOfOriginInSplitMapAreInSameComponentAndViceVersa()
        {
            ConnectivityMap standardMap = BuildStandardTestMap();
            MapSplitter     splitter    = new MapSplitter(standardMap.RoomConnectionGraph.Edges, standardMap.GetEdgeBetweenRooms(9, 10), 1);

            Assert.AreEqual(splitter.RoomComponentIndex(9), splitter.OriginComponentIndex);
            Assert.AreEqual(splitter.RoomComponentIndex(10), splitter.NonOriginComponentIndex);
        }
Beispiel #2
0
        public void RoomsOnSideOfOriginInMultiplySplitMapAreInOneComponent()
        {
            ConnectivityMap standardMap  = BuildStandardTestMap();
            var             edgesToSplit = new List <TaggedEdge <int, string> >();

            edgesToSplit.Add(standardMap.GetEdgeBetweenRooms(10, 11));
            edgesToSplit.Add(standardMap.GetEdgeBetweenRooms(3, 5));

            MapSplitter splitter = new MapSplitter(standardMap.RoomConnectionGraph.Edges, edgesToSplit, 1);

            CollectionAssert.AreEquivalent(new List <int>(new int[] { 1, 2, 3, 4, 7, 8, 9, 10 }), splitter.MapComponent(splitter.OriginComponentIndex).ToList());
        }
Beispiel #3
0
        public IEnumerable<int> GetNodesOnStartSideOfConnection(Connection dividingConnection)
        {
            //Check the edge is in the reduced map (will throw an exception if can't find)
            var foundEdge = mapWithoutCycles.GetEdgeBetweenRoomsNoCycles(dividingConnection.Source, dividingConnection.Target);

            //Remove all areas behind the locked door
            MapSplitter allowedMap = new MapSplitter(mapWithoutCycles.mapNoCycles.Edges, foundEdge, startVertex);

            //Find the component of this broken graph that is connected to the start vertex -
            //This component contains the vertices accessible with these clues
            return allowedMap.MapComponent(allowedMap.RoomComponentIndex(startVertex));
        }
    public override GameObject Generate()
    {
        Map map = config.MapGenerator.Generate();

        IHeightMap     floor     = config.FloorHeightMapModule.GetHeightMap();
        IHeightMap     ceiling   = config.CeilingHeightMapModule.GetHeightMap();
        CaveWallModule caveWalls = config.WallModule;

        Map[,] mapChunks         = MapSplitter.Subdivide(map);
        CaveMeshes[,] caveChunks = GenerateCaveChunks(mapChunks, config.CaveType, config.Scale, floor, ceiling, caveWalls);
        ThreeTierCave cave = new ThreeTierCave(caveChunks);

        AssignMaterials(cave, config.FloorMaterial, config.WallMaterial, config.CeilingMaterial);

        return(cave.GameObject);
    }
        /** Get valid rooms to place a clue, where rooms behind edgeToLock are inaccessible and rooms behind doors needing lockedClues are inaccessible */
        private IEnumerable<int> GetValidRoomsToPlaceClue(List<string> doorsToAvoidIds, Connection edgeToLock, IEnumerable<int> lockedClues)
        {
            //Check the edge is in the reduced map (will throw an exception if can't find)
            List<TaggedEdge<int, string>> foundEdge = new List<TaggedEdge<int, string>>(); ;
            if (edgeToLock != null)
                foundEdge.Add(mapNoCycles.GetEdgeBetweenRoomsNoCycles(edgeToLock.Source, edgeToLock.Target));

            //Find all doors that depend on any door with a locked clue.
            //We can't place a clue for our new door behind any of these
            var allDoorsDependentOnLockedClueDoors = lockedClues.SelectMany(c => GetDependentDoorIndices(c));
            var allInaccessibleDoors = lockedClues.Union(allDoorsDependentOnLockedClueDoors).Distinct();

            //Add to the list any doors we want to avoid (this can be used to localise clues to parts of levels etc.)
            var allDoorsToAvoid = doorsToAvoidIds.Select(id => GetDoorById(id).LockIndex);
            var allInaccessibleDoorsAndAvoidedDoors = allInaccessibleDoors.Union(allDoorsToAvoid);

            //Retrieve the door edges in the forbidden list
            //Note that some ids correspond to objectives, so these are avoided by the ugly SelectMany
            var forbiddenDoorEdges = allInaccessibleDoorsAndAvoidedDoors.SelectMany(
                doorIndex => doorMap.ContainsKey(doorIndex) ? new List<TaggedEdge<int, string>> { doorMap[doorIndex].DoorEdge } : new List<TaggedEdge<int, string>>());
            //Add this edge (can't put clue behind our own door) - NB: hacky way to union with a single item
            var allForbiddenDoorEdges = forbiddenDoorEdges.Union(foundEdge).Distinct();

            //Remove all areas behind any locked door
            MapSplitter allowedMap = new MapSplitter(mapNoCycles.mapNoCycles.Edges, allForbiddenDoorEdges, startVertex);

            //Find the component of this broken graph that is connected to the start vertex - this is the candidate subtree
            var allowedNodes = allowedMap.MapComponent(allowedMap.RoomComponentIndex(startVertex));

            return allowedNodes;
        }
        private IEnumerable<Objective> GetObjectivesBehindLockedEdge(TaggedEdge<int, string> foundEdge)
        {
            MapSplitter splitMap = new MapSplitter(mapNoCycles.mapNoCycles.Edges, foundEdge, startVertex);

            //Lists of all clues in vertices which are in the locked tree
            var newlyLockedObjectiveLists = objectiveRoomMap.Where(kv => splitMap.RoomComponentIndex(kv.Key) == splitMap.NonOriginComponentIndex).Select(kv => kv.Value);
            //Flattened to one long list
            return newlyLockedObjectiveLists.SelectMany(o => o);
        }
        public IEnumerable<int> GetAccessibleVerticesWithClues(IEnumerable<int> lockedDoorsForCluesAndObjectives)
        {
            //Find all the locked edges not accessible by our clues
            var allDoors = doorMap.Keys;

            //How many keys we have for each locked item
            var allClues = lockedDoorsForCluesAndObjectives.ToList();
            Dictionary<int, int> noCluesForDoors;

            //Test objectives in a n^2 loop and add any liberated clues
            var openedObjectives = new HashSet<Objective>();
            int openedObjectivesCount;

            do {
                openedObjectivesCount = openedObjectives.Count();
                noCluesForDoors =  allClues.GroupBy(c => c).ToDictionary(g => g.Key, g => g.Count());
                var unlockedObjectives = objectiveMap.Where(obj => noCluesForDoors.ContainsKey(obj.Value.LockIndex) &&
                                               noCluesForDoors[obj.Value.LockIndex] >= obj.Value.NumCluesRequired)
                                               .Select(d => d.Value);

                var newlyUnlockedObjectives = unlockedObjectives.Except(openedObjectives);
                var newClues = newlyUnlockedObjectives.SelectMany(obj => obj.OpenLockIndex);
                allClues.AddRange(newClues);

                //Seems that ordering here is important - ensure we have got the new clues before we add to openObjectives (lazy evaluation)
                foreach (var obj in newlyUnlockedObjectives) openedObjectives.Add(obj);
            } while(openedObjectivesCount != openedObjectives.Count());

            noCluesForDoors = allClues.GroupBy(c => c).ToDictionary(g => g.Key, g => g.Count());

            var unlockedDoors = doorMap.Where(d => noCluesForDoors.ContainsKey(d.Value.LockIndex) &&
                                                   noCluesForDoors[d.Value.LockIndex] >= d.Value.NumCluesRequired)
                                       .Select(d => d.Key);

            var lockedDoors = allDoors.Except(unlockedDoors);

            //Remove all areas behind any locked door
            var lockedEdges = lockedDoors.Select(d => doorMap[d].DoorEdge);
            MapSplitter allowedMap = new MapSplitter(mapNoCycles.mapNoCycles.Edges, lockedEdges, startVertex);

            //Find the component of this broken graph that is connected to the start vertex -
            //This component contains the vertices accessible with these clues
            return allowedMap.MapComponent(allowedMap.RoomComponentIndex(startVertex));
        }
Beispiel #8
0
        public void RoomsOnSideOfOriginInMultiplySplitMapAreInOneComponent()
        {
            ConnectivityMap standardMap = BuildStandardTestMap();
            var edgesToSplit = new List<TaggedEdge<int, string>>();
            edgesToSplit.Add(standardMap.GetEdgeBetweenRooms(10, 11));
            edgesToSplit.Add(standardMap.GetEdgeBetweenRooms(3, 5));

            MapSplitter splitter = new MapSplitter(standardMap.RoomConnectionGraph.Edges, edgesToSplit, 1);

            CollectionAssert.AreEquivalent(new List<int>(new int[] { 1, 2, 3, 4, 7, 8, 9, 10 }), splitter.MapComponent(splitter.OriginComponentIndex).ToList());
        }
Beispiel #9
0
        public void RoomsOnSideOfOriginInSplitMapAreInSameComponentAndViceVersa()
        {
            ConnectivityMap standardMap = BuildStandardTestMap();
            MapSplitter splitter = new MapSplitter(standardMap.RoomConnectionGraph.Edges, standardMap.GetEdgeBetweenRooms(9, 10), 1);

            Assert.AreEqual(splitter.RoomComponentIndex(9), splitter.OriginComponentIndex);
            Assert.AreEqual(splitter.RoomComponentIndex(10), splitter.NonOriginComponentIndex);
        }