2017-11-26 14 views
1

私は迷路を再帰的に作成するプログラムを書き終えましたが、各ステップの後に迷路を描く方法を見つけ出すことはできませんでした。迷路への変更は、次の再帰呼び出しの前に発生します。迷路はグリッドとしてJPanelにあらかじめレンダリングされており、次の再帰呼び出しの前に​​を使用して、プログラムを各ステップにレンダリングさせようとしました(私が以前に再描画しようとした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; 

} 

私はJPanelを設定しました。それぞれのセルを4方向のそれぞれに壁があるかどうかに基づいて個別に描画します。

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

_「迷路の再描画ができません」_ - それはどういう意味ですか?このヘルプの使い方を知るには、[help]にアクセスして[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という別の質問を投稿してください。

関連する問題