Connection AddRoomToRandomOpenDoor(TemplatedMapGenerator gen, RoomTemplate templateToPlace, RoomTemplate corridorTemplate, int distanceFromDoor)
        {
            int attempts    = 20;
            int thisAttempt = 0;

            do
            {
                try
                {
                    return(gen.PlaceRoomTemplateAlignedWithExistingDoor(templateToPlace, corridorTemplate, RandomDoor(gen), 0, distanceFromDoor));
                }
                catch (ApplicationException)
                {
                    thisAttempt++;
                }
            } while (thisAttempt < attempts);

            return(null);
        }
        private int PlaceRandomConnectedRooms(TemplatedMapGenerator templatedGenerator, int roomsToPlace, int maxRoomDistance)
        {
            int roomsPlaced = 0;
            int attempts    = 0;

            //This uses random distances and their might be collisions so we should avoid infinite loops
            int maxAttempts = roomsToPlace * 5;

            //Terminate when all rooms placed or no more potential door sites
            do
            {
                if (roomsPlaced == 0)
                {
                    //Place a random room at a location near the origin
                    try
                    {
                        templatedGenerator.PlaceRoomTemplateAtPosition(RandomRoom(), new Point(Game.Random.Next(maxRoomDistance), Game.Random.Next(maxRoomDistance)));
                        roomsPlaced++;
                    }
                    catch (ApplicationException) { }

                    attempts++;
                }
                else
                {
                    //Find a random potential door and try to grow a random room off this
                    var randomRoom       = RandomRoom();
                    var randomDoorInRoom = Game.Random.Next(randomRoom.PotentialDoors.Count);
                    try
                    {
                        templatedGenerator.PlaceRoomTemplateAlignedWithExistingDoor(randomRoom, corridorTemplates[0], RandomDoor(templatedGenerator),
                                                                                    randomDoorInRoom,
                                                                                    Game.Random.Next(maxRoomDistance));
                        roomsPlaced++;
                    }
                    catch (ApplicationException) { }

                    attempts++;
                }
            } while (roomsPlaced < roomsToPlace && attempts < maxAttempts && templatedGenerator.HaveRemainingPotentialDoors());
            return(roomsPlaced);
        }
        private int PlaceRandomConnectedRooms(TemplatedMapGenerator templatedGenerator, int roomsToPlace, RoomTemplate roomToPlace, RoomTemplate corridorToPlace, int minCorridorLength, int maxCorridorLength, Func <int> doorPicker)
        {
            int roomsPlaced = 0;
            int attempts    = 0;

            //This uses random distances and their might be collisions so we should avoid infinite loops
            int maxAttempts = roomsToPlace * 5;

            //Terminate when all rooms placed or no more potential door sites
            do
            {
                //Find a random potential door and try to grow a random room off this

                //Use a random door, or the function passed in
                int randomNewDoorIndex;
                if (doorPicker == null)
                {
                    //Random door
                    randomNewDoorIndex = Game.Random.Next(roomToPlace.PotentialDoors.Count);
                }
                else
                {
                    randomNewDoorIndex = doorPicker();
                }

                int corridorLength = Game.Random.Next(minCorridorLength, maxCorridorLength);

                try
                {
                    templatedGenerator.PlaceRoomTemplateAlignedWithExistingDoor(roomToPlace, corridorToPlace, RandomDoor(templatedGenerator), randomNewDoorIndex,
                                                                                corridorLength);

                    roomsPlaced++;
                }
                catch (ApplicationException) { }

                attempts++;
            } while (roomsPlaced < roomsToPlace && attempts < maxAttempts && templatedGenerator.HaveRemainingPotentialDoors());
            return(roomsPlaced);
        }
        public void RoomTemplateMayBeRetrievedAfterAddingAlignedRoom()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, null, mapGen.PotentialDoors[0], 0, 0);

            Assert.AreEqual(room2, mapGen.GetRoomTemplatesInWorldCoords()[1].Room);
        }
        public void RoomCantBeReplacedWithLargeRooms()
        {
            //Load sample template 8x4
            RoomTemplate baseRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate joinedRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            RoomTemplate replacementRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testoverlap3.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(baseRoom, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(joinedRoom, null, mapGen.PotentialDoors[0], 0, 0);

            Assert.IsFalse(mapGen.ReplaceRoomTemplate(0, new Connection(0, 1), replacementRoom, 0));
        }
        public void RoomReplacedWithSmallRoomsCantThenBeMadeLargeAgain()
        {
            //Load sample template 8x4
            RoomTemplate baseRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate joinedRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            RoomTemplate replacementRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testoverlap2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(baseRoom, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(joinedRoom, null, mapGen.PotentialDoors[0], 0, 0);

            mapGen.ReplaceRoomTemplate(0, new Connection(0, 1), replacementRoom, 0);

            //Here we use the knowledge that we deleted index 0, so the new replacement room is at index 1
            Assert.IsFalse(mapGen.ReplaceRoomTemplate(0, new Connection(0, 1), baseRoom, 0));
        }
        public void ReplaceRoomsHaveTheSameIds()
        {
            //Load sample template 8x4
            RoomTemplate baseRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate joinedRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            RoomTemplate replacementRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testoverlap2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            var originalId = mapGen.PlaceRoomTemplateAtPosition(baseRoom, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(joinedRoom, null, mapGen.PotentialDoors[0], 0, 0);

            var placementSucess = mapGen.ReplaceRoomTemplate(0, new Connection(0, 1), replacementRoom, 0);

            var roomTemplateById = mapGen.GetRoomTemplateById(originalId).Room;

            //This is a bit weak as an integration test - the replacement room gets rotated hence the strange comparison
            Assert.AreEqual(replacementRoom.Height, roomTemplateById.Width);
        }
        public void RoomCanBeReplacedWithSmallerRoomsWithAlignmentCorrected()
        {
            //Load sample template 8x4
            RoomTemplate baseRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate joinedRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            RoomTemplate replacementRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testoverlap2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(baseRoom, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(joinedRoom, null, mapGen.PotentialDoors[0], 0, 0);

            var replaceSuccess = mapGen.ReplaceRoomTemplate(0, new Connection(0,1), replacementRoom, 0);

            //Check replacement was successful and terrain is correct
            var map = mapBuilder.MergeTemplatesIntoMap(GetStandardTerrainMapping());
            Assert.AreEqual(MapTerrain.Wall, map.mapSquares[4, 1].Terrain);
        }
        public void ExcessAreaFromReplacedRoomsAreRemovedWhenSmallerRoomReplacesThem()
        {
            //Load sample template 8x4
            RoomTemplate baseRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate joinedRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            RoomTemplate replacementRoom = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testoverlap2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(baseRoom, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(joinedRoom, null, mapGen.PotentialDoors[0], 0, 0);

            mapGen.ReplaceRoomTemplate(0, new Connection(0, 1), replacementRoom, 0);

            var map = mapBuilder.MergeTemplatesIntoMap(GetStandardTerrainMapping());
            Assert.AreEqual(MapTerrain.Void, map.mapSquares[0, 0].Terrain);
        }
        public void PotentialDoorsAreRemovedAfterRoomsAreAligned()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");
            RoomTemplate corridor1 = LoadTemplateFromFileRogueBasin("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, null, mapGen.PotentialDoors[0], 0, 1);

            Assert.AreEqual(0, mapGen.PotentialDoors.Count);
        }
        public void CorrectPotentialDoorsAreRemovedAfterMultiDoorsRoomsAreConnectedByACorridor()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.test4doors.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.test2doors.room");
            RoomTemplate corridor1 = LoadTemplateFromFileRogueBasin("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, null, mapGen.PotentialDoors[3], 1, 1);

            var expectedDoors = new List<Point>(new Point[] { new Point(3, 0), new Point(0, 1), new Point(7, 1),
                                                              new Point(6, 6)});
            var actualDoors = mapGen.PotentialDoors.Select(d => d.MapCoords);

            CollectionAssert.AreEquivalent(expectedDoors.ToList(), actualDoors.ToList());
        }
        public void ConnectingDoorsBetweenTwoRoomsAlignedWithACorridorCanBeIdentified()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");
            RoomTemplate corridor1 = LoadTemplateFromFileRogueBasin("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, corridor1, mapGen.PotentialDoors[0], 0, 5);

            var room1ToCorridorDoor = mapGen.GetDoorForConnection(new Connection(0, 2));
            var room2ToCorridorDoor = mapGen.GetDoorForConnection(new Connection(1, 2));

            Assert.AreEqual(new Point(4, 3), room1ToCorridorDoor.MapCoords);
            Assert.AreEqual(new Point(4, 8), room2ToCorridorDoor.MapCoords);
        }
        public void AligningARoomWithNoCorridorReturnsTheConnectionToTheNewRoom()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            Assert.AreEqual(new Connection(0, 1),
                mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, null, mapGen.PotentialDoors[0], 0, 0));
        }
        public void AddingTwoAlignedRoomsWithACorridorGivesThreeConnectedNodeGraph()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");
            RoomTemplate corridor1 = LoadTemplateFromFileRogueBasin("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, corridor1, mapGen.PotentialDoors[0], 0, 2);

            var connectivityMap = mapGen.ConnectivityMap;

            //Ensure all connections are ordered for comparison purposes
            //It's a bit yuck having to know how indexes are set. I should probably refactor to throw exceptions rather than pass back false
            var allConnections = connectivityMap.GetAllConnections().Select(c => c.Ordered).ToList();
            CollectionAssert.AreEquivalent(new List<Connection>(new Connection[] { new Connection(0, 2), new Connection(1, 2) }), allConnections);
        }
        public void AddingTwoAlignedRoomsGiveTwoConnectedNodeGraph()
        {
            //Load sample template 8x4
            RoomTemplate room1 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom1.room");
            RoomTemplate room2 = LoadTemplateFromFile("DDRogueTest.testdata.vaults.testalignmentroom2.room");

            TemplatedMapBuilder mapBuilder = new TemplatedMapBuilder();
            TemplatedMapGenerator mapGen = new TemplatedMapGenerator(mapBuilder);

            mapGen.PlaceRoomTemplateAtPosition(room1, new Point(0, 0));
            mapGen.PlaceRoomTemplateAlignedWithExistingDoor(room2, null, mapGen.PotentialDoors[0], 0, 1);

            var connectivityMap = mapGen.ConnectivityMap;
            var allConnections = connectivityMap.GetAllConnections().ToList();

            CollectionAssert.AreEquivalent(new List<Connection>(new Connection[] { new Connection(0, 1) }), allConnections);
        }