/// <summary> /// Prior corridor generation simply looks for other rooms and paths to connect to. /// There is no guarantee that every room can be reached from a given room. /// Here we attempt to find rooms unconnected to the largest graph, and connect /// them by *spawning a new door and attempting to generate a new corridor*. /// /// Because there may be limited space for corridors, we must not waste it, so we discard /// any new doors+corridors that make a duplicate connection. /// /// There may be unconnected rooms even after this, but they are very rare. /// Moreover, because stair and key generation use the connected graph, /// any isolated rooms are harmless. /// </summary> /// <param name="chanceToTurn"></param> public void MakeDungeonACompleteGraph(double chanceToTurn) { List <Room> unconnectedRooms = Dungeon.FindUnconnectedRooms(Dungeon.GetRandomRoom()); int tries = 0; while (unconnectedRooms.Count > 0 && tries < Dungeon.Rooms.Count) { foreach (Room r in unconnectedRooms) { r.FlagDebug(); } Room room = unconnectedRooms[Rng.Next(0, unconnectedRooms.Count)]; Tile door = room.GenerateDoor(); if (door != null) { door.Debug = true; // Avoid wasting doors on paths that don't connect anywhere new bool allowConnectionToConnectedArea = false; GenerateCorridor(door, chanceToTurn, allowConnectionToConnectedArea); } unconnectedRooms = Dungeon.FindUnconnectedRooms(Dungeon.GetRandomRoom()); ++tries; } }
/// <summary> /// Choose a random start room. /// Choose the farthest room from that as the goal room. /// Choose a room with medium distance to place the key in. /// /// Rooms are ordered by BFS so the heuristic is number of rooms+paths crossed. /// </summary> public void GenerateStairsAndKey() { // Although very unlikely, it is possible not all rooms at this point are connected // Choose a random room that belongs to the connected dungeon Room startRoom; List <Room> roomsFromStart; do { startRoom = Dungeon.GetRandomRoom(); roomsFromStart = Dungeon.FindConnectedRooms(startRoom); }while (roomsFromStart.Count * 2 < Dungeon.Rooms.Count); int totalRooms = roomsFromStart.Count; // DEBUG: Draw BFS order on screen for (int i = 0; i < totalRooms; ++i) { roomsFromStart[i].GetRandomTile().Text = i.ToString(); } // The goal room is the farthest room encountered in the breadth-first search // The room with the key is somewhere in the middle Room goalRoom = roomsFromStart[totalRooms - 1]; Room keyRoom = roomsFromStart[Rng.Next((int)(totalRooms * 0.4), (int)(totalRooms * 0.6))]; startRoom.GetRandomTile().Space = Space.StairsUp; goalRoom.GetRandomTile().Space = Space.StairsDown; keyRoom.GetRandomTile().Space = Space.Key; }