简体   繁体   English

Java-无法突破这种递归方法

[英]Java - Can't break out of this recursive method

I am trying to implement a depht first search alogrithm (my code is probably horrible, I'm sorry). 我正在尝试实现一个简短的首次搜索算法(我的代码可能太可怕了,对不起)。 Now I wanted to make this a recursive method but I just can't seem to be able to break out of it once the end condition is met. 现在,我想使它成为递归方法,但是一旦满足最终条件,我似乎就无法摆脱它。 The first if-conditional you see in the method should break out of the method. 您在方法中看到的第一个if条件应该突破该方法。 When I was debugging the project it reached the return statement and then immediately jumped to the end of the method. 当我调试项目时,它到达了return语句,然后立即跳转到方法的末尾。 But instead of stopping the whole thing it went back to the while(!allNeighboursVisited) loop and went on in an infinite loop. 但是与其停止整个过程, while(!allNeighboursVisited)回到while(!allNeighboursVisited)循环并无限循环。

I was trying to solve this by myself which did not work and started searching in the web, but I just could not find any solution to my problem. 我试图自己解决这个无法解决的问题,因此开始在网络上搜索,但找不到解决方案。

EDIT: Decided to share the link to the project on my github for you guys to try it out: https://github.com/Equiphract/Maze 编辑:决定共享链接到我的github上的项目,供大家尝试: https : //github.com/Equiphract/Maze

EDIT 2: Updated the code; 编辑2:更新了代码; I hacked it together so please don't expect anything that is pleasant to look at :) 我一起砍死了,所以不要指望有什么令人愉快的:)

Here is the recursive method: 这是递归方法:

public void depthFirstSearch(int x, int y, Tile[][] maze) {
    // Return method after every Tile is visited.
    if (this.visitedCounter == maze.length * maze[0].length) {
        this.stack.clear();
        return;
    }

    Tile currentTile = maze[x][y];
    Random r = new Random();
    int neighbourAmount = currentTile.getNeighbourAmount();
    boolean allNeighboursVisited = false;
    int stopCounter = 0;

    // If it is a new Tile, mark it as visited
    if (!currentTile.isVisited()) {
        currentTile.setVisited(true);
        this.visitedCounter++;
        stack.add(currentTile);
    }

    // Check if neighbours are not yet visited and "visit" one of them.
    while (!allNeighboursVisited) {
        int random;
        do {
            random = r.nextInt(neighbourAmount);
        } while (this.excludeList.contains(random));

        Tile neighbour = currentTile.getNeighbours().get(random);
        if (!neighbour.isVisited()) {
            if (neighbour.getX() == currentTile.getX() - 1) {
                currentTile.getWall(4).setOpen(true);
                neighbour.getWall(2).setOpen(true);
            } else if (neighbour.getX() == currentTile.getX() + 1) {
                currentTile.getWall(2).setOpen(true);
                neighbour.getWall(4).setOpen(true);
            } else if (neighbour.getY() == currentTile.getY() - 1) {
                currentTile.getWall(1).setOpen(true);
                neighbour.getWall(3).setOpen(true);
            } else if (neighbour.getY() == currentTile.getY() + 1) {
                currentTile.getWall(3).setOpen(true);
                neighbour.getWall(1).setOpen(true);
            }
            this.excludeList.clear();
            depthFirstSearch(neighbour.getX(), neighbour.getY(), maze);
            if (this.visitedCounter == maze.length * maze[0].length) {
                this.stack.clear();
                return;
            }
        } else {
            this.excludeList.add(random);
            stopCounter++;
        }

        if (stopCounter == neighbourAmount) {
            allNeighboursVisited = true;
        }
    }

    // If every neighbour has already been visited, go back one Tile.
    if (!this.stack.isEmpty()) {
        this.stack.remove(this.stack.size() - 1);
        if (!this.stack.isEmpty()) {
            Tile backtrackTile = this.stack.get(this.stack.size() - 1);
            this.excludeList.clear();
            depthFirstSearch(backtrackTile.getX(), backtrackTile.getY(), maze);
            if (this.visitedCounter == maze.length * 3) {
                this.stack.clear();
                return;
            }
        }
        this.excludeList.clear();
    }
}

You know what, here is the Tile-Object (sorry for the high amount of edits in this short period): 您知道什么,这是Tile-Object(抱歉,在短时间内进行了大量编辑):

public class Tile {
    private ArrayList<Wall> walls;
    private ArrayList<Tile> neighbours;
    private int x;
    private int y;
    private boolean visited;

    /*
     * Constructor of the Tile class.
     */
    public Tile(int x, int y) {
        this.walls = new ArrayList<Wall>();
        this.neighbours = new ArrayList<Tile>();

        this.walls.add(new Wall(1));
        this.walls.add(new Wall(2));
        this.walls.add(new Wall(3));
        this.walls.add(new Wall(4));

        this.x = x;
        this.y = y;
        this.visited = false;
    }

    /*
     * Returns the ArrayList walls.
     */
    public ArrayList<Wall> getWalls() {
        return walls;
    }

    /*
     * Returns the value of visited.
     */
    public boolean isVisited() {
        return visited;
    }

    /*
     * Sets the value of visited to a specified value.
     * 
     * @param visited a boolean value
     */
    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    /*
     * Returns a wall with the specified position.
     * 
     * @param position the position of the wall
     */
    public Wall getWall(int position) {
        for(Wall w : this.walls) {
            if(w.getPosition() == position) {
                return w;
            }
        }
        return null;
    }

    public int getNeighbourAmount() {
        return this.neighbours.size();
    }

    public ArrayList<Tile> getNeighbours(){
        return this.neighbours;
    }


    /*
     * Adds a Tile to the ArrayList neighbours-
     * 
     * @param t a Tile
     */
    public void addNeighbour(Tile t) {
        this.neighbours.add(t);
    }

    /**
     * @return the x
     */
    public int getX() {
        return x;
    }

    /**
     * @return the y
     */
    public int getY() {
        return y;
    }
}

Ok I think I found a solution to my question. 好的,我认为我找到了解决问题的方法。 It is far from perfect and needs a lot of optimisation, maybe one of you guys want to do that and post it here^^. 它远非完美,需要大量优化,也许你们中的一个想要这样做并将其发布在这里^^。

My main mistake was not adding returns after each time I invoked the method recursively, which resulted in an endless-loop. 我的主要错误是每次递归调用该方法后都没有增加收益,这导致了无限循环。

Here is my solution: 这是我的解决方案:

public void depthFirstSearch(int x, int y, Tile[][] maze) {
    // Return method after every Tile is visited.
    if (this.visitedCounter == maze.length * maze[0].length) {
        this.stack.clear();
        return;
    }

    Tile currentTile = maze[x][y];
    Random r = new Random();
    int neighbourAmount = currentTile.getNeighbourAmount();
    boolean allNeighboursVisited = false;
    int stopCounter = 0;

    // If it is a new Tile, mark it as visited
    if (!currentTile.isVisited()) {
        currentTile.setVisited(true);
        this.visitedCounter++;
        stack.add(currentTile);
    }

    // Check if neighbours are not yet visited and "visit" one of them.
    while (!allNeighboursVisited) {
        int random;
        do {
            random = r.nextInt(neighbourAmount);
        } while (this.excludeList.contains(random));

        Tile neighbour = currentTile.getNeighbours().get(random);
        if (!neighbour.isVisited()) {
            if (neighbour.getX() == currentTile.getX() - 1) {
                currentTile.getWall(4).setOpen(true);
                neighbour.getWall(2).setOpen(true);
            } else if (neighbour.getX() == currentTile.getX() + 1) {
                currentTile.getWall(2).setOpen(true);
                neighbour.getWall(4).setOpen(true);
            } else if (neighbour.getY() == currentTile.getY() - 1) {
                currentTile.getWall(1).setOpen(true);
                neighbour.getWall(3).setOpen(true);
            } else if (neighbour.getY() == currentTile.getY() + 1) {
                currentTile.getWall(3).setOpen(true);
                neighbour.getWall(1).setOpen(true);
            }
            this.excludeList.clear();
            depthFirstSearch(neighbour.getX(), neighbour.getY(), maze);
            return;
        } else {
            this.excludeList.add(random);
            stopCounter++;
        }

        if (stopCounter == neighbourAmount) {
            allNeighboursVisited = true;
        }
    }

    // If every neighbour has already been visited, go back one Tile.
    if (!this.stack.isEmpty()) {
        this.stack.remove(this.stack.size() - 1);
        if (!this.stack.isEmpty()) {
            Tile backtrackTile = this.stack.get(this.stack.size() - 1);
            this.excludeList.clear();
            depthFirstSearch(backtrackTile.getX(), backtrackTile.getY(), maze);
            return;
        }
        this.excludeList.clear();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM