public static EmptyGrid ProcessMap(EmptyGrid map, RandomRoomWithCorridorSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        List <Corridor> corridorsList = new List <Corridor>();

        // Generate random rooms
        List <Room> roomList = GenerateRandomRooms(ref corridorsList, ref map.width, ref map.height, ref settings);

        // Random room placement on map
        for (int i = 0; i < roomList.Count; i++)
        {
            Room room = roomList[i];
            DrawRectangularRoom(ref map.values, room);
        }
        for (int i = 0; i < corridorsList.Count; i++)
        {
            BresenhamLine(ref map.values, corridorsList[i].startPoint.x, corridorsList[i].startPoint.z, corridorsList[i].endPoint.x, corridorsList[i].endPoint.z, corridorsList[i].direction);
        }

        // Connect floor tiles that are between single wall
        if (settings.hasCleanup)
        {
            CleanUpRoomPlacement(ref map.values, ref map.width, ref map.height);
        }

        Random.state = initialState;

        return(map);
    }
    public static TileMapSettings PreprocessMap(TileMapSettings mapSettings, RandomRoomWithCorridorSettings settings)
    {
        if (settings.roomsMinWidth < 3)
        {
            settings.roomsMinWidth = 3;
        }
        if (settings.roomsMinHeight < 3)
        {
            settings.roomsMinHeight = 3;
        }
        if (settings.roomsMaxWidth < settings.roomsMinWidth)
        {
            settings.roomsMaxWidth = settings.roomsMinWidth;
        }
        if (settings.roomsMaxHeight < settings.roomsMinHeight)
        {
            settings.roomsMaxHeight = settings.roomsMinHeight;
        }
        if (settings.minCorridorLength < 0)
        {
            settings.minCorridorLength = 0;
        }
        if (settings.maxCorridorLength < settings.minCorridorLength)
        {
            settings.maxCorridorLength = settings.minCorridorLength;
        }
        if (mapSettings.mapWidth < settings.roomsMaxWidth + settings.maxCorridorLength)
        {
            mapSettings.mapWidth = settings.roomsMaxWidth + settings.maxCorridorLength;
        }
        if (mapSettings.mapHeight < settings.roomsMaxHeight + settings.maxCorridorLength)
        {
            mapSettings.mapHeight = settings.roomsMaxHeight + settings.maxCorridorLength;
        }

        return(mapSettings);
    }
    private static List <Room> GenerateRandomRooms(ref List <Corridor> corridors, ref int mapWidth, ref int mapHeight, ref RandomRoomWithCorridorSettings settings)
    {
        List <Room> roomList       = new List <Room>();
        int         roomsMinWidth  = settings.roomsMinWidth - 1;
        int         roomsMinHeight = settings.roomsMinHeight - 1;

        int roomWidth  = Random.Range(roomsMinWidth, settings.roomsMaxWidth);
        int roomHeight = Random.Range(roomsMinHeight, settings.roomsMaxHeight);
        int x          = Random.Range(0, mapWidth - roomWidth);
        int z          = Random.Range(0, mapHeight - roomHeight);

        // center room
        Room newRoom = new Room(Mathf.FloorToInt((mapWidth - roomWidth) * 0.5f), Mathf.FloorToInt((mapHeight - roomHeight) * 0.5f), roomWidth, roomHeight);

        roomList.Add(newRoom);

        int roomsCreated          = 1;
        int placementTriesCounter = 0;
        int spawnRestartsCounter  = 0;

        bool canContinuePlacement = true;

        while (canContinuePlacement)
        {
            if (settings.tryToGenerateSpecificAmountOfRooms && (roomsCreated == settings.amountOfRoomsToGenerate))
            {
                canContinuePlacement = false;
                continue;
            }

            if (placementTriesCounter >= settings.roomPlacementTriesCount)
            {
                if (settings.tryToGenerateSpecificAmountOfRooms && (spawnRestartsCounter < settings.timesToRestartSpawn))
                {
                    roomsCreated          = 1;
                    placementTriesCounter = 0;
                    roomList.Clear();
                    newRoom = new Room(Mathf.FloorToInt((mapWidth - roomWidth) * 0.5f), Mathf.FloorToInt((mapHeight - roomHeight) * 0.5f), roomWidth, roomHeight);
                    roomList.Add(newRoom);
                    spawnRestartsCounter++;
                }
                else
                {
                    canContinuePlacement = false;
                }
            }

            roomWidth  = Random.Range(roomsMinWidth, settings.roomsMaxWidth);
            roomHeight = Random.Range(roomsMinHeight, settings.roomsMaxHeight);

            int maxX = mapWidth - roomWidth - 1;
            int maxZ = mapHeight - roomHeight - 1;

            Direction  spawnDir  = (Direction)Random.Range(0, 4);
            Coordinate doorCoord = roomList[Random.Range(0, roomList.Count)].GetRandomWallCoordinate(spawnDir);

            x = doorCoord.x;
            z = doorCoord.z;

            int corridorLength = Random.Range(settings.minCorridorLength, settings.maxCorridorLength);

            if (spawnDir == Direction.North || spawnDir == Direction.South)
            {
                z       += spawnDir == Direction.North ? corridorLength + 1 : -corridorLength - 1;
                spawnDir = spawnDir == Direction.North ? Direction.South : Direction.North;
            }
            else
            {
                x       += spawnDir == Direction.East ? corridorLength + 1 : -corridorLength - 1;
                spawnDir = spawnDir == Direction.East ? Direction.West : Direction.East;
            }

            newRoom = new Room(x, z, roomWidth, roomHeight);

            Coordinate endDoorCoord = newRoom.GetRandomWallCoordinate(spawnDir);

            int xOffset = endDoorCoord.x - x;
            int zOffset = endDoorCoord.z - z;
            x -= xOffset;
            z -= zOffset;
            endDoorCoord.x -= xOffset;
            endDoorCoord.z -= zOffset;

            bool isOverlapping = false;

            placementTriesCounter++;

            if (x < 0 || x > maxX)
            {
                continue;
            }
            if (z < 0 || z > maxZ)
            {
                continue;
            }

            newRoom.ChangePosition(x, z);

            foreach (Room room in roomList)
            {
                if (settings.canShareSingleWall ? room.IsOverlappingExclusive(newRoom) : room.IsOverlapping(newRoom))
                {
                    isOverlapping = true;
                    break;
                }
            }

            if (isOverlapping)
            {
                continue;
            }
            else
            {
                roomsCreated++;
                roomList.Add(newRoom);
                corridors.Add(new Corridor(doorCoord, endDoorCoord, spawnDir));
            }
        }

        return(roomList);
    }