2017-11-26 22 views
1

미로를 반복적으로 생성하는 프로그램을 작성했지만 각 단계마다 미로를 그리는 방법을 찾지 못했습니다. 미로에 대한 변경 사항은 다음 재귀 호출 이전에 발생합니다. 미로는 사각형 격자로 JPanel에 미리 렌더링되어 있으며 다음 재귀 호출 전에 JPanel.repaint을 사용하여 각 단계를 렌더링하도록했습니다 (이전에 다시 그리기를 시도한 내 generate 메서드 내에서 주석이 있습니다. 문제 내가 무엇을하려고 미로는 단지. 마지막에 한 번에 완성 된 제품 (경로, 벽 모두와 함께 미로 등) 렌더링 첨부 나의 재귀 generate 방법이다.재귀 미로 생성기를 사용하여 각 단계를 그릴 수 있습니까?

private static boolean generate(int x, int y) { 
    System.out.println("xcord: " + x + ", ycord: " + y); 
    //panel.repaint(); when i have repaint here, it renders the entire maze at the end 
    a[x][y].visited = true; 
    if (unvisitedCells == 0) { // if you have visited all of the cells, maze is done generating 
     System.out.println("done"); 
     return true; 
    } 
    int movesTried = 0; // keeps track of which directions have been tried 
    int currentMove = (int) (Math.random() * 4); // try moving a random direction first (0 = north, 1 = east, etc.) 
    while (movesTried < 4) { // continue as long as all four moves havent been tried 
     // north move 
     if (a[x][y].northCell != null && a[x][y].northCell.visited != true && currentMove == 0) { 
      a[x][y].northCell.visited = true; 
      a[x][y].northWall = false; 
      a[x][y].northCell.southWall = false; 
      unvisitedCells -= 1; 
      // tried repainting here, but had no effect 
      if (generate(x, y - 1)) { 
       return true; // move successful 
      } 
     } 
     // east move 
     if (a[x][y].eastCell != null && a[x][y].eastCell.visited != true && currentMove == 1) { 
      a[x][y].eastCell.visited = true; 
      a[x][y].eastWall = false; 
      a[x][y].eastCell.westWall = false; 
      unvisitedCells -= 1; 
      // tried repainting here, but had no effect 
      if (generate(x + 1, y)) { 
       return true; // move successful 
      } 
     } 
     // south move 
     if (a[x][y].southCell != null && a[x][y].southCell.visited != true && currentMove == 2) { 
      a[x][y].southCell.visited = true; 
      a[x][y].southWall = false; 
      a[x][y].southCell.northWall = false; 
      unvisitedCells -= 1; 
      // tried repainting here, but had no effect 
      if (generate(x, y + 1)) { 
       return true; // move successful 
      } 
     } 
     // west move 
     if (a[x][y].westCell != null && a[x][y].westCell.visited != true && currentMove == 3) { 
      a[x][y].westCell.visited = true; 
      a[x][y].westWall = false; 
      a[x][y].westCell.eastWall = false; 
      unvisitedCells -= 1; 
      // tried repainting here, but had no effect 
      if (generate(x - 1, y)) { 
       return true; // move successful 
      } 
     } 
     movesTried++; // another move has been tried 
     if (currentMove == 3 && movesTried < 4) { 
      currentMove = 0; // wraps back to north move if maze started at a move greater than 0, and you 
           // have more moves to try 
     } else { 
      currentMove++; 
     } 
    } 
    // at this point, all 4 moves have been tried, and there are no possible moves 
    // from the current maze cell 
    return false; 
} 

각각의 셀 렌더링 MazeCell 클래스에 보관 된 정보를 사용하여 JPanel에 개별적으로 전송할 수 있습니다.

public class MazeCell { 

public boolean northWall = true; 
public boolean eastWall = true; 
public boolean southWall = true; 
public boolean westWall = true; 

public MazeCell northCell = null; 
public MazeCell eastCell = null; 
public MazeCell southCell = null; 
public MazeCell westCell = null; 

public boolean visited = false; 

} 

여기에 각각 4 방향의 벽이 있는지 여부에 따라 각 셀을 개별적으로 그려주는 JPanel을 설정했습니다.

panel = new JPanel() { 

     private static final long serialVersionUID = 1L; 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      a[0][0].northWall = false; 
      a[mazeSize - 1][mazeSize - 1].southWall = false; 
      for (int y = 0; y < mazeSize; y++) { 
       for (int x = 0; x < mazeSize; x++) { 
        if (a[x][y].northWall) { 
         g.drawLine(100 + (x * 25), 100 + (y * 25), 100 + (x * 25) + 25, 100 + (y * 25)); 
        } 
        if (a[x][y].eastWall) { 
         g.drawLine(100 + (x * 25) + 25, 100 + (y * 25), 100 + (x * 25) + 25, 100 + (y * 25) + 25); 
        } 
        if (a[x][y].southWall) { 
         g.drawLine(100 + (x * 25), 100 + (y * 25) + 25, 100 + (x * 25) + 25, 100 + (y * 25) + 25); 
        } 
        if (a[x][y].westWall) { 
         g.drawLine(100 + (x * 25), 100 + (y * 25), 100 + (x * 25), 100 + (y * 25) + 25); 
        } 
       } 
      } 
     } 
    }; 
+0

_ "미로를 다시 그릴 수 없습니다"_ - 그게 무슨 뜻입니까? 이 도움말을 사용하는 방법을 배우려면 [도움말]을 방문하고 [ask]를 읽으십시오. –

+0

감사합니다. 나는 모호성을 제거하기 위해 내 게시물을 편집했습니다. – tjulich

+1

죄송합니다. _ "각 단계를 렌더링 할 때 미로를 얻을 수 없습니다."_ 여전히 의미가 없습니다. 단계를 렌더링하려는 코드는 어디에 있습니까? '한 걸음 내딛다'는 것은 무엇을 의미합니까? 단계를 렌더링하려고하면 어떻게됩니까? 예외가 있니? 아무 반응이 없습니다? 컴퓨터는 1980 년대의 싼 영화처럼 불꽃을 뿜어 낸다. –

답변

3

워프 긴 과정 SwingWorker와 (generate(int x, int y)), 그리고 GUI를 업데이트 할 수 있습니다. 필요한 경우

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.GridLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingWorker; 

public class RecursiveGuiUpdate extends JFrame { 

    private final int SIZE = 4; 
    JLabel[][] grid = new JLabel[SIZE][SIZE]; 

    RecursiveGuiUpdate() { 

     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     add(getGrid(), BorderLayout.NORTH); 
     JButton paint = new JButton("Paint"); 
     paint.addActionListener(a -> updateGui()); 
     add(paint, BorderLayout.SOUTH); 
     pack(); 
     setVisible(true); 
    } 

    private void updateGui() { 
     new Task().execute(); 
    } 

    private Component getGrid() { 
     JPanel panel = new JPanel(new GridLayout(SIZE, SIZE)); 
     for(int i=0; i<=(SIZE-1); i++) { 
      for(int j=0; j<=(SIZE-1); j++) { 
       JLabel l = new JLabel(i+"-"+j, JLabel.CENTER); 
       l.setOpaque(true); 
       panel.add(l); 
       grid[i][j] = l; 
      } 
     } 
     return panel; 
    } 

    class Task extends SwingWorker<Void,Void> { 

     @Override 
     public Void doInBackground() { 
      updateGui(0, 0); 
      return null; 
     } 

     @Override 
     public void done() { } 

     //recursively set labels background 
     void updateGui(int i, int j) { 

      System.out.println(i+"-"+j); 
      //set random, background color 
      grid[i][j].setBackground(new Color((int)(Math.random() * 0x1000000))); 

      try { 
       Thread.sleep(500); //simulate long process 
      } catch (InterruptedException ex) { ex.printStackTrace();} 

      if((i==(SIZE-1))&&(j==(SIZE-1))) { return; } 

      if(i<(SIZE-1)) { 
       updateGui(++i, j); 
      }else { 
       i=0; 
       updateGui(i, ++j); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new RecursiveGuiUpdate(); 
    } 
} 

, 당신이 얻을 및 중간 결과를 처리 process(java.util.List)을 무시할 수 있습니다 예를 들면 다음과 같습니다.
해당 솔루션을 코드에 적용하는 데 도움이 필요하면 mcve과 함께 다른 질문을 게시하십시오.