Ошибка с рекурсивной функцией в алгоритме генерации лабиринта в Java с использованием Eclipse - PullRequest
0 голосов
/ 03 апреля 2012

это моя первая попытка в Java, поэтому я решил написать алгоритм генерации лабиринта. Я уже написал это на C #, поэтому подумал, что было бы удобно написать что-то, что я делал раньше. Я использую Eclipse для написания и компиляции Java.

После того, как я закончил писать свою программу, и она не дала мне никаких ошибок или чего-либо еще, я попытался запустить ее, но она выдает странный вывод в консоли: он говорит: at helloWorld.mazeAlgorithm(helloWorld.java:52) столько раз, сколько Высота и ширина лабиринта, который я пытаюсь создать. Я понятия не имею, что делать, и я также не мог ничего найти в Интернете.

(и я знаю, что мой код, вероятно, действительно плохой, но я спешил, и я просто хотел посмотреть, смогу ли я что-нибудь написать быстро.) Вот оно:

import java.applet.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;

public class helloWorld extends Applet
{
    final int horizontalSize = 10;
    final int verticalSize = 10;
    final int LEFT = 1;
    final int UP = 2;
    final int RIGHT = 3;
    final int DOWN = 4;

    ArrayList<cell> visitedCells;
    public void paint(Graphics g)
    {
        initialize(g);
        cell startCell = new cell();
        startCell.x = 0;
        startCell.y = 0;
        mazeAlgorithm(startCell, g);
    }
    public void initialize (Graphics g)
    {

        for (int x = 0; x< horizontalSize*10+1; x=x+10)
        {
            g.drawLine(x, 0, x, verticalSize*10);
        }

        for (int y = 0; y < verticalSize*10+1; y=y+10)
        {
            g.drawLine(0, y, horizontalSize*10, y);
        }

        visitedCells = new ArrayList<cell>();
        cell currentCell = new cell();
        currentCell.x = 0;
        currentCell.y = 0;
        visitedCells.add(currentCell);

    }
    public void mazeAlgorithm(cell currentCell, Graphics g)
    {
        ArrayList<cell> neighbourCells = getUnvisitedNeighbourCells(currentCell);
        while(neighbourCells.size()> 0)
        {
            cell nextCell = neighbourCells.get(randomNumber(neighbourCells.size()-1));
            removeWall(nextCell, g);
            visitedCells.add(nextCell);
            mazeAlgorithm(nextCell, g);
            neighbourCells = getUnvisitedNeighbourCells(currentCell);
        }
        return;
    }

    public ArrayList<cell> getUnvisitedNeighbourCells(cell cellToCheck)
    {
        ArrayList<cell> unvisitedNeighbourCells = new ArrayList<cell>();
        cell tempCell = new cell();

        tempCell.x = cellToCheck.x-1;
        tempCell.y = cellToCheck.y;
        tempCell.direction = LEFT;
        if (cellToCheck.x > 0 && !visitedCells.contains(tempCell))
            unvisitedNeighbourCells.add(tempCell);
        tempCell.x = cellToCheck.x;
        tempCell.y = cellToCheck.y-1;
        tempCell.direction = UP;
        if (cellToCheck.y > 0 && !visitedCells.contains(tempCell))
            unvisitedNeighbourCells.add(tempCell);
        tempCell.x = cellToCheck.x+1;
        tempCell.y = cellToCheck.y;
        tempCell.direction = RIGHT;
        if (cellToCheck.x < horizontalSize-1 && !visitedCells.contains(tempCell))
            unvisitedNeighbourCells.add(tempCell);
        tempCell.x = cellToCheck.x;
        tempCell.y = cellToCheck.y+1;
        tempCell.direction = DOWN;
        if (cellToCheck.y < verticalSize-1 && !visitedCells.contains(tempCell))
            unvisitedNeighbourCells.add(tempCell);
        return unvisitedNeighbourCells;
    }

    public void removeWall(cell Cell, Graphics g)
    {
        g.setColor(Color.WHITE);
        switch(Cell.direction)
        {
        case LEFT:
            g.drawLine(Cell.x*10, Cell.y*10-10, Cell.x*10, Cell.y*10);
            break;
        case UP:
            g.drawLine(Cell.x*10-10, Cell.y*10, Cell.x*10, Cell.y*10);
            break;
        case RIGHT:
            g.drawLine(Cell.x*10-10, Cell.y*10-10, Cell.x*10-10, Cell.y*10);
            break;
        case DOWN:
            g.drawLine(Cell.x*10-10, Cell.y*10-10, Cell.x*10, Cell.y*10-10);
            break;
        }
        return;
    }

    private int randomNumber(int max)
    {
        Random random = new Random();
        return random.nextInt(max);
    }
}

class cell
{
    public int x;
    public int y;
    public int direction;
}

Заранее большое спасибо!

Ответы [ 2 ]

1 голос
/ 03 апреля 2012

Это проблема метода, а не проблема кодирования или Java.Большинство учеников начинают так: пишите весь код, который у вас в голове, и запускайте его, когда закончите.

Но это способ программирования гуру, и есть шансы, что вам понадобятся годы опыта, чтобы он работал таким образом.

Программирование подчиняется парадигме «разделяй и властвуй»: когда у вас большие проблемы, вы разбиваете их на части и решаете небольшие проблемы.Если есть даже слишком большие ... вы знаете, что делать: вы ломаете это снова.И т. Д.

Это позволяет вам решать более конкретные проблемы и, более того, возможность проверить, хорошо ли решена каждая небольшая проблема.Это подход.

Никто не хочет решать этот вопрос, так как есть слишком много проблем, чтобы решить их сразу.

  • Разделите их, изолируйте каждый метод, вызовите его в небольшой программе и найдите свои проблемыпо одному.(Знаете ли вы о тестах?)
  • Отслеживайте свою программу (поместите system.out.println) везде, где, по вашему мнению, необходимо распечатать значения.Или отладить.Но вы должны понимать и уметь запускать все вместе со своей программой.
1 голос
/ 03 апреля 2012

Реальная проблема - это, вероятно, StackOverflowException, и вот почему:

getUnvisitedNeighborCells создает новый tempCell и затем проверяет, содержит ли его посещенная коллекция. Поскольку вы не переопределили метод equals в классе ячеек, он будет проверять только ссылку на объект, которая не будет прежней, потому что вы только что создали новый экземпляр для tempCell, поэтому вызов contains возвращает false, так что вы никогда на самом деле никогда не будете пометить ячейку как посещенную.

Чтобы исправить это, вы должны переопределить метод equals (и hashCode) для вашего объекта ячейки, чтобы он сравнивал x, y и направление, тогда ваш вызов содержимого вернет true, и вы выйдете из своего бесконечного обхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...