我正在用java编写一个迷宫解算器程序,但我无法弄清楚如何添加某些功能。现在我让它为我硬编码的2D字符数组工作。
我需要按钮:
一个滚动条,可以控制在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();
}
}
答案 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());