网格DFS可视化 [英] Grid DFS visualization

查看:67
本文介绍了网格DFS可视化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在一个项目中尝试创建迷宫生成器.
到目前为止,我有一个网格,它是一个Cell类的2D数组,一个将面板绘制为JFrame的JPanel,以及一个使用深度优先搜索来访问网格中每个Cell的函数.
访问单元后,单元的颜色在网格上变为黑色.
我的问题是网格上的重新绘制太快了,无论如何我可以放慢时间或设置一个计时器在几秒钟后重新绘制.这是下面的代码

  import java.util.Arrays;导入java.util.Stack;导入javax.swing.JFrame;导入javax.swing.JPanel;导入javax.swing.Timer;导入java.awt.Graphics;导入java.awt.event.ActionEvent;导入java.awt.event.ActionListener;导入java.security.SecureRandom;公共类Maze扩展了JPanel实现ActionListener {私人牢房[] []迷宫;私人int暗淡的;专用Stack< Cell>S =新的Stack< Cell>();私有SecureRandom num = new SecureRandom();计时器t;公共迷宫(int din){昏暗=丁;maze = new Cell [dims] [dims];}公共空隙生成器(){for(int i = 0; i< maze.length; i ++){for(int j = 0; j< maze [0] .length; j ++){maze [i] [j] =新的Cell(i,j);}}}公共布尔checkAll(){for(int i = 0; i< maze.length; i ++){for(int j = 0; j< maze [0] .length; j ++){if(!maze [i] [j] .visited)返回false;}}返回true;}公共无效adjlist(){for(int i = 0; i< maze.length; i ++){for(int j = 0; j< maze [0] .length; j ++){if(i + 1> = 0& i + 1<变暗){maze [i] [j] .neighbor.add(maze [i + 1] [j]);}if(i-1> = 0& i-1<暗淡){maze [i] [j] .neighbor.add(maze [i-1] [j]);}if(j-1> = 0&& j-1<变暗){maze [i] [j] .neighbor.add(maze [i] [j-1]);}if(j + 1> = 0&& j + 1<变暗){maze [i] [j] .neighbor.add(maze [i] [j + 1]);}}}}公共无效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());单元格temp1 = maze [x.row] [x.column] .neighbor.get(randnum);如果(!maze [temp1.row] [temp1.column] .visited){DFS(迷宫[temp1.row] [temp1.column]);}否则if(maze [x.row] [x.column] .neighbor.isEmpty()){S.pop();maze [S.peek().row] [S.peek().column] .visited = false;DFS(S.pop());}别的{if(S.size()-1 == 0)返回;单元格温度=空;对于(单元格c:迷宫[x.row] [x.column] .neighbor){如果(!maze [c.row] [c.column] .visited){temp = c;DFS(温度);}}如果(temp == null){S.pop();maze [S.peek().row] [S.peek().column] .visited = false;DFS(S.pop());}}}}公共无效涂料(图形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();尝试 {Thread.sleep(5000);} catch(InterruptedException e){//TODO自动生成的catch块e.printStackTrace();}}公共静态void main(String [] args){迷宫p =新迷宫(10);p.generator();p.adjlist();System.out.println("------------------------");JFrame f =新的JFrame();f.setTitle(迷宫");f.add(p);f.setVisible(true);f.setSize(700,700);f.setLocationRelativeTo(null);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);p.DFS(新Cell(1,5));}@Override公共无效actionPerformed(ActionEvent e){}} 

单元格类

  import java.util.ArrayList;公共类单元格{public int行,列;布尔访问;ArrayList< Cell>邻居;公用单元格(int i,int j){行=我;列= j;访问=假;邻居=新的ArrayList< Cell>();}public int getRow(){返回this.row;}公共诠释getCol(){返回this.column;}公共字符串toString(){返回this.row +" + this.column;}} 

解决方案

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

  import java.awt.Dimension;导入java.awt.Graphics;导入java.util.Random;导入javax.swing.JFrame;导入javax.swing.JPanel;导入javax.swing.SwingWorker;公共类迷宫扩展了JPanel {私有最终单元格[] []迷宫;私人最终int暗淡;private static final int SIZE = 35;公共迷宫(int dim){setPreferredSize(new Dimension(dim * SIZE,dim * SIZE));昏暗=昏暗;maze = new Cell [dims] [dims];}公共无效生成器(){for(int i = 0; i< maze.length; i ++){for(int j = 0; j< maze [0] .length; j ++){maze [i] [j] =新的Cell(i,j);//设置一些任意的初始日期if(i%2 == 0&& j%2 == 0){maze [i] [j] .setVisited(true);}}}}公共无效DFS(){新的DFSTask().execute();}@Overridepublic void paintComponent(Graphics g)//覆盖paintComponent而不是paint{super.paintComponent(g);for(int row = 0; row< maze.length; row ++){for(int col = 0; col< maze [0] .length; col ++){g.drawRect(SIZE * row,SIZE * col,SIZE,SIZE);if(maze [row] [col] .visited){g.fillRect(SIZE * row,SIZE * col,SIZE,SIZE);}}}}公共静态void main(String [] args){迷宫p =新迷宫(10);p.generator();JFrame f =新的JFrame();f.setLocationRelativeTo(null);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.add(p);f.pack();f.setVisible(true);p.DFS();}//使用秋千工作者执行长任务DFSTask类扩展了SwingWorker< Void,Void>.{私有静态最终长整型DELAY = 1000;私人最终的随机兰德=新的Random();@Override公共虚空doInBackground(){dfs();返回null;}@Override公共无效done(){}void dfs(){//模拟重复更新gui的长进程while(true){//无限循环,仅用于演示//更新信息int row = rand.nextInt(dims);int col = rand.nextInt(dims);maze [row] [col] .setVisited(!maze [row] [col] .isVisited());repaint();//更新jpanel尝试 {Thread.sleep(DELAY);//模拟漫长的过程} catch(ex.InterruptedException){ex.printStackTrace();}}}}}细胞类{私人最终int行,列;布尔访问;公用单元格(int i,int j){行=我;列= j;访问=假;}int getRow(){返回行;}int getColumn(){返回列;}boolean isVisited(){返回已访问;}void setVisited(boolean Visited){this.visited = Visited;}@Override公共字符串toString(){返回行+" +列;}} 

有关使用 SwingWorker 的更多信息,请参见

Hello guys I am working on a project where I am trying to create a maze generator.
So far I have a gird that is a 2D array of a Cell class and a JPanel that paints the grid to a JFrame and a function which uses Depth first Search to visit each Cell in the grid.
When the Cell has been visited the Cell color changes to black on the grid.
My problem is the repaint on the grid is too fast is there anyway I can slow the time or set a timer to repaint after a number of seconds. Here is the code below

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) {}

    }

The cell class

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

解决方案

The following code demonstrates the use of SwingWorker to demonstrate performing long tasks (in your case dfs search) which update the gui.
Specific dfs information was removed because they are not relevant:

import java.awt.Dimension;
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 final Cell [][] maze;
    private final int dims;
    private static final int SIZE = 35;

    public Maze(int dim) {
        setPreferredSize(new Dimension( dim*SIZE,dim*SIZE));
        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(SIZE*row, SIZE * col , SIZE, SIZE);
                if(maze[row][col].visited)
                {
                    g.fillRect(SIZE*row, SIZE * col , SIZE, SIZE);
                }
            }
        }
    }

    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.add(p);
        f.pack();
        f.setVisible(true);
        p.DFS();
    }

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

        private static final long DELAY = 1000;
        private final 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 final 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;
    }
}

For more information about using SwingWorker see doc


这篇关于网格DFS可视化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆