java网格DFS访问每个单元格

时间:2018-06-10 03:44:04

标签: java swing delay repaint

你好我们正在研究一个项目,我正在尝试创建一个迷宫生成器。
到目前为止,我有一个网格,它是一个Cell类的2D数组和一个JPanel,它将网格绘制到一个JFrame,一个函数使用Depth first Search来访问网格中的每个Cell。
访问单元格后,单元格颜色在网格上变为黑色。
我的问题是网格上的重绘速度太快无论如何我可以减慢时间或设置一个计时器在几秒钟后重新绘制。这是下面的代码

import java.util.Arrays;
import java.util.Stack;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.SecureRandom;

public class Maze extends JPanel implements ActionListener {
    private Cell [][] maze;
    private int dims;
    private Stack<Cell> S = new Stack<Cell>();
    private SecureRandom num = new SecureRandom();
    Timer t;

    public Maze(int din)
    {
        dims = din;
        maze = new Cell[dims][dims];        
    }

    public void generator()
    {
        for(int i = 0; i < maze.length; i++)
        {
            for (int j = 0;j < maze[0].length; j++)
            {
                maze[i][j] = new Cell(i,j);
            }
        }
    }

    public boolean checkAll()
    {
        for(int i = 0; i < maze.length; i++)
        {
            for (int j = 0;j < maze[0].length; j++)
            {
                if(!maze[i][j].visited)
                    return false;
            }
        }
        return true;
    }

    public void adjlist()
    {
        for(int i = 0; i < maze.length; i++)
        {
            for (int j = 0;j < maze[0].length; j++)
            {
                if(i+1 >= 0 && i+1 < dims)
            {
                maze[i][j].neighbor.add(maze[i+1][j]);

            }
            if(i-1 >= 0 && i-1 < dims)
            {
                maze[i][j].neighbor.add(maze[i-1][j]);          
            }
            if(j-1 >= 0 && j-1 < dims)
            {
                maze[i][j].neighbor.add(maze[i][j-1]);          
            }
            if(j+1 >= 0 && j+1 < dims)
            {
                maze[i][j].neighbor.add(maze[i][j+1]);          
            }
            }
        }
    }

    public void DFS(Cell x)
    {
        if (!checkAll() && !maze[x.row][x.column].visited) 
        {
            S.push(x);
            System.out.println(Arrays.toString(S.toArray()));
            maze[x.row][x.column].visited = true;
            int randnum = num.nextInt(maze[x.row][x.column].neighbor.size());
            Cell temp1 = maze[x.row][x.column].neighbor.get(randnum);
            if (!maze[temp1.row][temp1.column].visited) 
            {
                DFS(maze[temp1.row][temp1.column]);
            } 
            else if (maze[x.row][x.column].neighbor.isEmpty()) 
            {
                S.pop();
                maze[S.peek().row][S.peek().column].visited = false;
                DFS(S.pop());
            } 

            else 
            {
                if(S.size()-1 == 0)
                    return;
                Cell temp = null;
                for (Cell c : maze[x.row][x.column].neighbor) 
                {
                    if (!maze[c.row][c.column].visited) 
                    {
                        temp = c;
                        DFS(temp);                  
                    }
                }
                if (temp == null) {
                    S.pop();
                    maze[S.peek().row][S.peek().column].visited = false;
                    DFS(S.pop());
                }
            }
        }
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        for (int row = 0; row < maze.length; row++)
        {
            for (int col = 0; col < maze[0].length; col++)
            {
                g.drawRect(35*row, 35 * col , 35, 35);
                if(maze[row][col].visited)
                {
                    //t.start();
                    g.fillRect(35*row, 35 * col , 35, 35);
                    //t.setDelay(5000);                 
                }
            }
        }
        repaint();
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    }

    public static void main(String[] args)
    {
        Maze p = new Maze(10);
        p.generator();
        p.adjlist();
        System.out.println("------------------------");
        JFrame f = new JFrame();
        f.setTitle("Maze");
        f.add(p);
        f.setVisible(true);
        f.setSize(700, 700);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        p.DFS(new Cell(1,5));
    }


    @Override
    public void actionPerformed(ActionEvent e) {}

    }

细胞类

import java.util.ArrayList;

public class Cell{
    public int row, column;
    boolean visited;
    ArrayList<Cell> neighbor;

    public Cell(int i, int j)
    {
        row = i;
        column = j;
        visited = false;
        neighbor = new ArrayList<Cell>();
    }

    public int getRow()
    {
        return this.row;
    }

    public int getCol()
    {
        return this.column;
    }

    public String toString()
    {
        return this.row + " " + this.column;
    } 
  }

1 个答案:

答案 0 :(得分:0)

以下代码演示了如何使用SwingWorker演示执行更新gui的长任务(在您的情况下为dfs搜索)。
删除了特定的dfs信息,因为它们不相关:

import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

public class Maze extends JPanel {

    private Cell [][] maze;
    private int dims;

    public Maze(int dim)
    {
        dims = dim;
        maze = new Cell[dims][dims];
    }

    public void generator()
    {
        for(int i = 0; i < maze.length; i++)
        {
            for (int j = 0;j < maze[0].length; j++)
            {
                maze[i][j] = new Cell(i,j);
                //set some arbitrary initial date
                if(((i%2) ==0) && ((j%2) ==0)) {
                    maze[i][j].setVisited(true);
                }
            }
        }
    }

    public void DFS()
    {
        new DFSTask().execute();
    }

    @Override
    public void paintComponent(Graphics g) //override paintComponent not paint
    {
        super.paintComponent(g);
        for (int row = 0; row < maze.length; row++)
        {
            for (int col = 0; col < maze[0].length; col++)
            {
                g.drawRect(35*row, 35 * col , 35, 35);
                if(maze[row][col].visited)
                {
                    g.fillRect(35*row, 35 * col , 35, 35);
                }
            }
        }

    }

    public static void main(String[] args)
    {
        Maze p = new Maze(10);
        p.generator();
        JFrame f = new JFrame();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(380,400);
        f.add(p);
        f.setVisible(true);
        p.DFS();
    }

    //use swing worker perform long task
    class DFSTask extends SwingWorker<Void,Void> {

        private static final long DELAY = 1000;
        private Random rand = new Random();

        @Override
        public Void doInBackground() {
            dfs();
            return null;
        }

        @Override
        public void done() { }

        void dfs() { //simulates long process that repeatedly updates gui

            while (true){ //endless loop, just for demonstration
                //update info
                int row = rand.nextInt(dims);
                int col = rand.nextInt(dims);
                maze[row][col].setVisited(! maze[row][col].isVisited());
                repaint(); //update jpanel
                try {
                    Thread.sleep(DELAY); //simulate long process
                } catch (InterruptedException ex) { ex.printStackTrace();}
            }
        }
    }
}

class Cell{

    private int row, column;
    boolean visited;

    public Cell(int i, int j)
    {
        row = i;
        column = j;
        visited = false;
    }

    int getRow() {  return row; }

    int getColumn() {return column; }

    boolean isVisited() { return visited; }

    void setVisited(boolean visited) {  this.visited = visited;}

    @Override
    public String toString()
    {
        return row + " " + column;
    }
}

有关使用SwingWorker的详细信息,请参阅doc