为Maze Solver java程序添加功能

时间:2015-09-17 22:53:37

标签: java

我正在用java编写一个迷宫解算器程序,但我无法弄清楚如何添加某些功能。现在我让它为我硬编码的2D字符数组工作。

我需要按钮:

  1. 从文本文件加载迷宫(用户可以选择)并将其放入2D字符数组中。
  2. 启动迷宫(基本上是一个启动MazeApp.java中的solveMaze()方法的按钮)
  3. 一个滚动条,可以控制在solveMaze方法中的Thread.sleep()中的值。

    一个文本字段,可以显示迷宫中正在(或不是)的内容(即“无迷宫加载”,“迷宫加载”,“正在进行解决方案”,“此时已找到完成:” )

    处理GUI的MazeApp:

    import java.awt.*;
    import javax.swing.*;
    
    public class MazeApp extends JPanel implements Runnable {
        final private int cellSize = 20; // how big the cells/squares are
        final private int rows = 25; // how many rows are in the array (need to be able to get this info from txt file)
        final private int cols = 25; // how many columns are in the array (need to be able to get this info from txt file)
        private boolean mazeSolved = false; // boolean to check if maze is solved
        private boolean solutionExists = true;
        private int startLocX, startLocY; // ints used for '@' start location
        int cellLocX, cellLocY; // cell location that moves through the maze
    
    //    private char[][] easyMaze = {
    //            {'#','#', '#', '#', '#'},
    //            {'#','@', '.', '.', '#'},
    //            {'#','#', '#', '.', '#'},
    //            {'#','.', '.', '.', '#'},
    //            {'#','#', '#', '#', '#'},
    //            {'-','-', '-', '-', '-'},
    //            {'#','#', '#', '#', '#'},
    //            {'#','=', '.', '.', '#'},
    //            {'#','#', '#', '.', '#'},
    //            {'#','*', '.', '.', '#'},
    //            {'#','#', '#', '#', '#'},
    //    };
    
        //hard coded example 1 level maze with multiple finishes;
        private char[][] easyMaze = {
                {'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
                {'#','.','#','.','.','.','#','.','.','.','.','.','.','.','#','.','.','.','.','.','.','.','.','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','.','#','.','#','#','.','#','#','.','#','#','#','#','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','.','#','.','#','#','.','#','.','.','.','.','#','#','.','#'},
                {'#','.','.','.','#','.','#','.','#','#','.','#','.','#','#','.','#','.','#','.','.','#','#','.','#'},
                {'#','.','#','.','#','.','#','.','.','.','.','#','.','#','#','.','#','.','#','.','.','#','#','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','.','#','.','#','#','.','.','.','.','.','.','.','.','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','.','#','.','.','.','.','#','.','#','#','#','#','.','.','#'},
                {'#','.','.','.','#','.','.','.','#','#','.','#','.','#','#','.','#','.','#','.','#','.','.','.','#'},
                {'#','.','#','#','#','#','#','#','#','#','.','#','.','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','.','.','#','.','.','.','.','#','.','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','#','#','.','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','.','#','.','#','#','#','#','.','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','.','.','#','.','.','.','#','.','.','.','.','#','#','.','.','.','.','.','.','.','.','.','#'},
                {'#','#','#','#','#','#','.','#','#','#','#','#','#','#','#','.','#','.','#','#','#','.','#','.','#'},
                {'#','.','.','.','.','.','.','.','.','.','#','#','#','#','#','.','#','.','.','.','#','.','#','.','#'},
                {'#','.','#','.','#','#','#','#','#','#','#','#','#','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','.','.','.','.','.','.','.','.','.','.','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','#','#','#','#','#','#','#','#','.','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','.','.','.','.','.','.','.','.','.','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','.','#','#','#','#','#','#','#','#','#','.','#','.','#','.','#','.','#','.','#'},
                {'#','.','#','.','#','.','.','.','.','.','.','.','.','.','#','.','#','.','#','.','#','.','#','#','#'},
                {'#','@','#','.','#','#','.','#','#','#','#','.','.','.','#','.','#','.','#','.','#','.','#','#','#'},
                {'#','.','.','.','#','#','.','#','#','#','#','.','.','#','#','.','.','.','.','.','.','.','.','*','#'},
                {'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'}
        };
    
        // goes through array and paints cells
        public void paintComponent(Graphics myGrfx) {
    
            super.paintComponent(myGrfx);
    
            //for loop to paint the rows
            for(int i = 0;  i < rows; i++){
    
                //for loop to paint the cols
                for(int j = 0; j < cols; j++) {
                    if (i == cellLocX && j == cellLocY) {
                        myGrfx.setColor(Color.GREEN);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    } else if (easyMaze[i][j] == '#') {
                        myGrfx.setColor(Color.BLACK);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    } else if (easyMaze[i][j] == '*') {
                        myGrfx.setColor(Color.RED);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    } else if (easyMaze[i][j] == '.') {
                        myGrfx.setColor(Color.WHITE);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    } else if (easyMaze[i][j] == 'x') {
                        myGrfx.setColor(Color.LIGHT_GRAY);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    } else if (easyMaze[i][j] == '=') {
                        myGrfx.setColor(Color.BLUE);
                        myGrfx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                    }
                }
            }
        }
    
        // goes through the array to find '@', starts start locations points at i and j
        public void getStartPosition() {
            for(int i = 0;  i < rows; i++){
                for(int j = 0; j < cols; j++) {
                    if (easyMaze[i][j] == '@') {
                        startLocX = i;
                        startLocY = j;
                    }
                }
            }
        }
    
        public void getStairsPosition() {
            for(int i = 0;  i < rows; i++){
                for(int j = 0; j < cols; j++) {
                    if (easyMaze[i][j] == '=') {
                        startLocX = i;
                        startLocY = j;
                    }
                }
            }
        }
    
        // marks visited paths with an 'x', shaded light gray
        public void markPath(int locX, int locY){
            easyMaze[locX][locY] = 'x';
            cellLocX = locX;
            cellLocY = locY;
        }
    
        // method you have to use for threads, need to replace with timer stuff
        public void run() {
            getStartPosition();
            solveMaze(startLocX, startLocY);
        }
    
        // checks to see if the maze has found an exit
        public boolean isFinished(int locX, int locY) {
            if (easyMaze[locX][locY] == '*') {
                return true;
            } else {
                return false;
            }
        }
    
        // boolean that checks for walls
        public boolean outOfBounds(int locX, int locY) {
            if (easyMaze[locX][locY] == '#') {
                return true;
            } else {
                return false;
            }
        }
    
        // boolean to check if a cell has been visited
        public boolean haveVisited(int locX, int locY) {
            if (easyMaze[locX][locY] == 'x') {
    
                return true;
            } else {
                return false;
            }
        }
    
        public void noSolution() {
            for(int i = 0;  i < rows; i++){
                for(int j = 0; j < cols; j++) {
                    if (easyMaze[i][j] == '#' || easyMaze[i][j] == 'x') {
                        solutionExists = false;
                    }
                }
            }
        }
    
        // method that calls itself and checks for finish, walls, or already visited paths
        private void solveMaze(int locX, int locY) {
            if (isFinished(locX, locY)) {
                mazeSolved = true;
                JOptionPane.showMessageDialog(this, "Yay, we found the finish!");
                System.exit(0);
            }
    
            if (outOfBounds(locX, locY)) {
                return;
            }
    
            if (haveVisited(locX, locY)) {
                return;
            }
    
            if (!mazeSolved) {
                markPath(locX, locY);
                repaint();
                try {Thread.sleep(50); } catch (Exception e) { }
    
                solveMaze(locX, locY+1); // move right
                solveMaze(locX + 1,locY); // move down
                solveMaze(locX - 1, locY); // move up
                solveMaze(locX, locY - 1); // move left
            }
        } // end solveMaze
    } // end class
    

    这是测试类:

    import javax.swing.*;
    
    public class MazeTest {
        public static void main (String[] args) {
            JFrame maze = new JFrame();
            maze.setSize(750, 520);
            maze.setLocationRelativeTo(null);
            maze.setTitle("Maze Solver 1.0");
            MazeApp myMazeApp = new MazeApp();
            maze.setContentPane(myMazeApp);
            maze.setVisible(true);
            Thread myThread = new Thread(myMazeApp);
            myThread.start();
        }
    }
    

1 个答案:

答案 0 :(得分:0)

将以下代码添加到MazeApp应该可以解决问题:

private static final int initialSpeed = 50;
private static final int paddingTop = 30;
private static final int paddingLeft = 30;
private JButton loadMazeBtn = new JButton("Load Maze");
private JButton runMazeBtn = new JButton("Run Maze");
private JScrollBar speedBar = new JScrollBar(JScrollBar.HORIZONTAL);
private JLabel statusLabel = new JLabel("Starting up...");

private void add(JComponent component, int x, int y) {
    add(component);
    component.setLocation(x, y);
    component.setSize(component.getPreferredSize());
}

public MazeApp() {
    setLayout(null);

    int x = cols * cellSize + paddingLeft;
    int y = paddingTop;

    add(loadMazeBtn, x, y);
    add(runMazeBtn, x, y + 40);
    add(speedBar, x, y + 80);
    add(statusLabel, x, y + 120);

    loadMazeBtn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // Fill in your code to load the maze
        }
    });

    runMazeBtn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // Fill in your code to run the maze
        }
    });

    speedBar.setValue(initialSpeed);
}

// Call this method when you want to change the status text
// (i.e. "no maze loaded", "maze loaded", "solution in progress", "found finish at this point: ")
public void setStatusText(String text) {
    statusLabel.setText(text);
}

// Call this function to feed the Thread.sleep
public int getSpeed() {
    return speedBar.getValue();
}

您只需填写“加载迷宫”和“运行代码”的代码,并在状态发生变化时添加对setStatusText的调用。

对于“高速条”,将Thread.sleep中的solveMaze代码更改为

Thread.sleep(getSpeed());