2017-11-19 7 views
1

depht 첫 번째 검색 알고리즘을 구현하려고합니다. (내 코드는 아마도 끔찍한 데 미안합니다.) 이제 이것을 재귀 적 방법으로 만들고 싶었지만 일단 최종 조건이 충족되면 중단 할 수없는 것처럼 보입니다. 메소드에서 첫 번째 조건부가 발견되면 메소드에서 벗어나야합니다. 프로젝트를 디버깅 할 때 return 문에 도달 한 다음 즉시 메서드의 끝으로 이동했습니다. 그러나 모든 것을 멈추기보다는 while(!allNeighboursVisited) 루프로 돌아가 무한 루프를 반복했습니다.Java -이 재귀 적 메서드를 벗어날 수 없습니다.

나는이 문제를 해결하려고 노력했지만 웹에서 검색을 시작했지만 문제에 대한 해결책을 찾지 못했습니다.

편집 : 너희들은 그것을 밖으로 시도 내 GitHub의에서 프로젝트에 링크를 공유하기로 결정 https://github.com/Equiphract/Maze

편집 2 : 코드 업데이트; 나는 함께 그래서 여기에 :)

보는 즐거운 아무것도 재귀 적 방법이다 기대하지 마십시오 해킹 :

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(); 
    } 
} 

을 당신은 여기에 대한 죄송 타일 객체 (무엇인지 이 짧은 기간 동안 수정 량이 많음) :

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; 
    } 
} 
+0

:

여기 내 솔루션입니다! 나에게 Tile 객체를 주면 다음을 보겠습니다. – Stefan

+0

전체 프로그램을 볼 수있는 github 링크를 제공했습니다. java 파일은/src/maze에 있습니다. 편집 : 코드를 검토하기 전에 기다려, 하루 종일 몇 가지 변경 사항을, 나는 곧 게시물을 편집합니다. – Equiphract

답변

0

좋아요. 제 질문에 대한 해결책을 찾은 것 같습니다. 완벽하지 않고 최적화가 많이 필요합니다. 아마도 여러분 중 한 명은 그것을하고 여기에 게시하고 싶습니다 ^^.

내 실수는 반복적으로 메서드를 호출 할 때마다 반환을 추가하지 않아 무한 루프가 발생했습니다. 재미있는

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(); 
    } 
}