Как узнать количество дверей в комнате в процедурно сгенерированном подземелье?

В предисловии я расскажу немного больше о текущем проекте. Я работаю над игрой, которая помещает игрока в подземелье в виде комнаты. Вход/выход в комнаты осуществляется через двери.

Вот метод генератора(), который у меня есть для создателя пола.

Метод turn(int, int, int) принимает направление (случайно созданное число 0–3) и два начальных положения, а также координаты x и y и возвращает массив, содержащий предыдущие числа, но в зависимости от направления, один был изменен путем увеличения/уменьшения единицы. Например, если направление равно 0, это будет означать вверх, а координата у будет вычтена из 1. В возвращаемом массиве первое значение — это X, второе — это Y.

    int roomTag = 1; //tags the room as created

    int currentX = startLocation; //the column that navigates the map
    int currentY = startLocation;

    map[currentY][currentX] = roomTag;

    int rooms = 0;

    while(rooms < maxRooms) {
        int direction = randomRange(0, 4);

        currentX = turn(direction, currentX, currentY)[0];
        currentY = turn(direction, currentX, currentY)[1];
        if(currentX > 0 && currentY > 0  && currentX < maxSize && currentY < maxSize) {
            if(map[currentY][currentX] != roomTag) {
                map[currentY][currentX] = roomTag;
                roomList[currentY][currentX] = new NormalRoom(this, currentX, currentY, rooms);
                rooms++;
            }
        } else {
            currentX = startLocation;
            currentY = startLocation;
        }
    }

    roomList[startLocation][startLocation] = new StartRoom(this, startLocation, startLocation, 0);

На данный момент процедурная генерация работает отлично. Он каждый раз генерирует подземелье по-разному, и все комнаты соединены по горизонтали или вертикали по крайней мере с одной другой комнатой.

Комнаты просто содержат информацию о дверях, локации и врагах, если они есть. В комнатах есть метод поиска дверей для создания. Вот метод, который вызывается при создании экземпляра комнаты. Сначала он вызывается для получения количества дверей, которые должны быть созданы, затем устанавливает логическое значение created в true, затем снова запускает метод для создания/добавления дверей в массив.

    int doorIndex = doorCount - 1;
    int[][] tempMap = floor.getMap();

    if(yLocation > 0) {
        for(int i = 0; i < tempMap.length; i++) {
            for(int j = 0; j < tempMap.length; j++) {
                if(i == tempMap.length/2 && j == tempMap.length/2) System.out.print("() ");
                else if(tempMap[j][i] == 1) System.out.print("[] ");
                else System.out.print("    ");
            }
            System.out.println(" ");
        }
        if(tempMap[yLocation - 1][xLocation] == 1) {
            System.out.println("UP DOOR IN: (" + yLocation + ", " + xLocation + ")");
            if(created) {
                door[doorIndex] = new Door(0);
                doorIndex--;
            } else {
                doorCount++;
            }
        }
    }
    if(yLocation < floor.getMap().length - 1) {
        if(tempMap[yLocation + 1][xLocation] == 1) {
            System.out.println("DOWN DOOR IN: (" + yLocation + ", " + xLocation + ")");
            if(created) {
                door[doorIndex] = new Door(2);
                doorIndex--;
            } else {
                doorCount++;
            }
        }
    }
    if(xLocation < floor.getMap().length - 1) {
        if(tempMap[yLocation][xLocation + 1] == 1) {
            System.out.println("RIGHT DOOR IN: (" + yLocation + ", " + xLocation + ")");
            if(created) {
                door[doorIndex] = new Door(1);
                doorIndex--;
            } else {
                doorCount++;
            }
        }
    }
    if(xLocation > 0) {
        if(tempMap[yLocation][xLocation - 1] == 1) {
            System.out.println("LEFT DOOR IN: (" + yLocation + ", " + xLocation + ")");
            if(created) {
                door[doorIndex] = new Door(3);
            } else {
                doorCount++;
            }
        }
    }

    if(created) {
        for(int i = 0; i < door.length; i++) {
            door[i].instantiate();
        }
    }

Проблема, похоже, в том, что он никогда не создает левые двери и редко создает двери вверх. Кажется, я не могу понять, почему он это делает. Я застрял на этом некоторое время и, похоже, не могу найти причину этого, так как не могу найти никаких последовательности в этой проблеме.

Я склонялся к тому, чтобы публиковать меньше кода, но если нужно больше, дайте мне знать.

Заранее спасибо.

Изменить: возможно, я нашел решение. Учитывая тот факт, что метод вызывается во время создания экземпляров комнат, он не может найти другие комнаты, поскольку они еще не существуют. Комнаты могут создавать двери только для тех комнат, которые были созданы до нее. Если бы они были созданы позже, на карте они еще не были бы указаны как существующие.

Я постараюсь исправить проблему с учетом этого.

EDIT 2: Это была проблема. Создание комнат после создания карты исправило это. Я просто сделал так, чтобы создатель комнаты был отделен от создателя карты, а затем создал комнаты на основе карты.


person jlars789    schedule 14.01.2019    source источник
comment
Вы уверены, что ваши утверждения if верны? Ваше ylocation, кажется, составляет двери вверх и вправо, а ваши операторы xlocation, если делают двери влево и вниз, кажутся мне необычными, поскольку я ожидаю, что y будет отображаться вверх/вниз, а X - влево/вправо.   -  person Ferrybig    schedule 14.01.2019
comment
@Ferrybig Я заставил их напечатать не те вещи, извините. При создании объекта двери 0 = Вверх, 1 = Вправо, 2 = Вниз, 3 = Влево   -  person jlars789    schedule 14.01.2019


Ответы (1)


Проблема заключалась в том, что я создавал экземпляры комнат по мере их создания, и частью создания экземпляров комнат было определение количества и расположения дверей. Проблема в том, что я просил алгоритм найти еще не созданные комнаты.

Чтобы исправить это, я использовал карту, которую я создал ранее, это был массив 2DArray, где комнаты были отмечены 1, а все остальное — 0. После того, как карта была полностью создана, я перебрал карту и поместил комнату в координаты, отмеченные цифрой 1, в отдельном массиве 2DArray, содержащем объекты Room.

Двери теперь точно ведут в новые комнаты, как и предполагалось.

person jlars789    schedule 14.01.2019