Maze Generation выдает ошибку переполнения стека - PullRequest
0 голосов
/ 24 мая 2019

В моем коде генерации лабиринта я получаю ошибку переполнения стека, почему? Как мне это исправить? Это происходит только в конце. Если я закомментирую одно из утверждений if внутри оператора else, код работает нормально. Почему это? Я пытаюсь рекурсивно создать лабиринт, и я не уверен, правильно ли я это делаю

    public void generate(int row, int col) {

        rng = new Random();
        int move = rng.nextInt(4);

        if(hasUnvisited()==false) {
            System.out.println("e");
        }

        else if(move==0&&row+2<=19) {
            if (maze[row+2][col].getVisited()==false) {
                maze[row+1][col].remove();
            }
            maze[row][col].visit();
            generate(row+2,col);
        }
        else if(move==1&&row-2>=0) {
            if (maze[row-2][col].getVisited()==false) {
                maze[row-1][col].remove();
            }
            maze[row][col].visit();
            generate(row-2,col);
        }
        else if(move==2&&col+2<=19) {
            if (maze[row][col+2].getVisited()==false) {
                maze[row][col+1].remove();
            }
            maze[row][col].visit();
            generate(row,col+2);
        }
        else if(move==3&&col-2>=0) {
            if (maze[row][col-2].getVisited()==false) {
                maze[row][col-1].remove();
            }
            maze[row][col].visit();
            generate(row,col-2);
        }

        else {
            maze[row][col].visit();
            if (move==0) {
                generate(row-2,col);
            }

            else if (move==1) {
                generate(row+2,col);
            }

            else if (move==2) {
                generate(row,col-2);
            }

            else if (move==3) {
                generate(row,col+2);
            }
        }       
    }

Exception in thread "main" java.lang.StackOverflowError
    at java.util.Random.<init>(Unknown Source)
    at Maze.generate(Maze.java:41)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:94)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:94)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:88)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:88)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:88)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:94)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:94)
    at Maze.generate(Maze.java:88)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:88)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:67)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:74)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:60)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:53)
    at Maze.generate(Maze.java:67)

1 Ответ

0 голосов
/ 24 мая 2019

Ваш стек очень многословен, говоря вам две вещи:

  • У вас фактически есть переполнение стека, которое не вызвано забытым приращением индекса или чем-то подобным.
  • Код (на первый взгляд) не попадает в бесконечный цикл, потому что кадры стека оканчиваются на разных строках кода. Если бы это было иначе, у вас был бы бесконечный цикл. Он все еще может быть один (скрытый кажущейся случайностью), но гораздо менее вероятен.

В настоящее время всякий раз, когда вы выполняете рекурсивный вызов (вызов generate в функции generate), вы увеличиваете размер стека. Вы передаете все текущие состояния поля в кадр стека, и виртуальная машина должна помнить об этом, продолжая следующий нижний вызов generate. Поскольку это, вероятно, также вызовет саму себя и т. Д., В какой-то момент стек становится слишком большим для хранения в стеке.

У вас есть два варианта, на мой взгляд. Либо увеличьте максимальный размер стека при запуске виртуальной машины set JAVA_OPTS=%JAVA_OPTS% -Xms1024m -Xmx1024m или (лучший вариант) переработать ваш код, чтобы он был итеративным Таким образом, вы не увеличиваете свой стек до бесконечности. Что бы это значило:

Вместо того, чтобы работать повторно (делать вызовы самого метода), вам придется создавать циклы, которые будут обращаться к различным уровням стека с помощью явного проектирования. Весь рекурсивный код (в теории ИТ) может быть преобразован в итеративный код, поэтому это должно быть возможно. Однако вы должны думать иначе.

...