// Generate a single room
    public DungeonRoom GenerateRoom(int id, QuadTree _quadTree)
    {
        // Center of the room
        XY roomCenter = new XY();

        roomCenter.x = Random.Range(ROOM_WALL_BORDER + _quadTree.boundary.Left() + ROOM_MIN_SIZE / 2.0f, _quadTree.boundary.Right() - ROOM_MIN_SIZE / 2.0f - ROOM_WALL_BORDER);
        roomCenter.y = Random.Range(ROOM_WALL_BORDER + _quadTree.boundary.Bottom() + ROOM_MIN_SIZE / 2.0f, _quadTree.boundary.Top() - ROOM_MIN_SIZE / 2.0f - ROOM_WALL_BORDER);

        // Half size of the room
        XY roomHalf = new XY();

        float halfX  = (_quadTree.boundary.Right() - roomCenter.x - ROOM_WALL_BORDER);
        float halfX2 = (roomCenter.x - _quadTree.boundary.Left() - ROOM_WALL_BORDER);

        if (halfX2 < halfX)
        {
            halfX = halfX2;
        }
        if (halfX > ROOM_MAX_SIZE / 2.0f)
        {
            halfX = ROOM_MAX_SIZE / 2.0f;
        }

        float halfY  = (_quadTree.boundary.Top() - roomCenter.y - ROOM_WALL_BORDER);
        float halfY2 = (roomCenter.y - _quadTree.boundary.Bottom() - ROOM_WALL_BORDER);

        if (halfY2 < halfY)
        {
            halfY = halfY2;
        }
        if (halfY > ROOM_MAX_SIZE / 2.0f)
        {
            halfY = ROOM_MAX_SIZE / 2.0f;
        }

        roomHalf.x = Random.Range((float)ROOM_MIN_SIZE / 2.0f, halfX);
        roomHalf.y = Random.Range((float)ROOM_MIN_SIZE / 2.0f, halfY);

        // Eliminate ugly zones
        if (ROOM_UGLY_ENABLED == false)
        {
            float aspect_ratio = roomHalf.x / roomHalf.y;
            if (aspect_ratio > ROOM_MAX_RATIO || aspect_ratio < 1.0f / ROOM_MAX_RATIO)
            {
                return(GenerateRoom(id, _quadTree));
            }
        }

        // Create AABB
        AABB randomAABB = new AABB(roomCenter, roomHalf);

        // create room
        DungeonRoom room = new DungeonRoom(id, randomAABB, _quadTree);

        // Dig the room in our tilemap
        DigRoom(room, randomAABB.BottomTile(), randomAABB.LeftTile(), randomAABB.TopTile() - 1, randomAABB.RightTile() - 1);

        // Return the room
        return(room);
    }