/// <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;
        }