Grid DFS可视化

问题描述 投票:-1回答:1

大家好,我正在一个项目中尝试创建迷宫生成器。到目前为止,我有一个网格,它是一个Cell类的2D数组,一个将面板绘制为JFrame的JPanel,以及一个使用深度优先搜索来访问网格中每个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;
    } 
  }
java swing delay repaint
1个回答
0
投票

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

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

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


enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.