Ява сетки DFS, чтобы посетить каждую ячейку - PullRequest
0 голосов
/ 10 июня 2018

Привет, ребята. Я работаю над проектом, в котором я пытаюсь создать генератор лабиринта.До сих пор у меня есть набор, который представляет собой 2D-массив класса Cell, и JPanel, который рисует сетку в JFrame, и функция, которая использует Поиск в глубину для посещения каждой ячейки в сетке.При посещении ячейки цвет ячейки меняется на черный на сетке.Моя проблема в том, что перерисовка на сетке слишком быстрая, есть ли я в любом случае, я могу замедлить время или установить таймер для перекраски через несколько секунд.Вот код ниже

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 голосов
/ 10 июня 2018

Следующий код демонстрирует использование SwingWorker для демонстрации выполнения длинных задач (в вашем случае поиск 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...