问题描述
迷宫问题求解2
• 使用深度优先的方法解决迷宫问题
• 规定迷宫的最外围为一圈墙,给出起点和终点要求输出一条正确的路径,但不要求为最短路径
• 使用opencv实现可视化,演示一个动态求解迷宫的过程
代码部分
Position.java 文件
package MazeGame;
//位置类,用语记录当前所走的位置
public class Position {
int x;
int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public Position(Position p) {
this.x = p.x;
this.y = p.y;
}
}
MyNode.java 文件
package MazeGame;
//自己所设置的点的位置
public class MyNode {
Position element;
MyNode next;
public MyNode(Position p) {
this.element = new Position(p);
this.next = null;
}
}
MyMaze.java 文件
package MazeGame;
import java.util.EmptyStackException;
//自己所设计的迷宫
public class MyMaze {
protected MyNode top = null;
public MyMaze() {
}
public void push(Position element) {
if (this.top == null) {
this.top = new MyNode(element);
} else {
MyNode current = new MyNode(element);
current.next = this.top;
this.top = current;
}
}
public Position pop() {
if (this.isEmpty()) {
throw new EmptyStackException();
} else {
Position p = this.top.element;
this.top = this.top.next;
return p;
}
}
public boolean isEmpty() {
return this.top == null;
}
}
Gird.java 文件
package MazeGame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//网格背景类
class Grid extends JButton implements ActionListener {
//墙
boolean isWall;
public Grid() {
this.isWall = false;
this.setBackground(Color.white);
this.addActionListener(this);
}
public Grid(int i) {
Font font = new Font("Serif", 1, 12);
this.isWall = true;
this.setText(String.valueOf(i));
this.setFont(font);
//this.setBackground(new Color(1.0F, 1.0F, 1.0F, 0.0F));
}
public void setWall() {
this.isWall = true;
this.setBackground(Color.BLACK);
}
public void actionPerformed(ActionEvent arg) {
if (this.isWall) {
this.isWall = false;
this.setBackground(Color.WHITE);
} else {
this.isWall = true;
this.setBackground(Color.BLACK);
}
}
/* public void click() {
if (this.isWall) {
this.isWall = false;
this.setBackground(Color.WHITE);
} else {
this.isWall = true;
this.setBackground(Color.BLACK);
}
}*/
}
Maze.java 文件
package MazeGame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Maze implements MouseListener {
static Grid[][] grid;
static MyMaze path;
static Position start;
static Position end;
static int WIDTH;
static int HEIGHT;
JTextField start1;
JTextField end1;
JTextField out;
boolean isMousePressed;
public Maze(int width, int height) {
WIDTH = width + 2;
HEIGHT = height + 2;
grid = new Grid[WIDTH][HEIGHT];
this.layout(width + 2, height + 2);
}
private void layout(int width, int height) {
int sideLength = 40;
int frameWidth = sideLength * width + 20;
int frameHeight = sideLength * (height + 2) + 32;
JFrame frame = new JFrame();
frame.setTitle("Maze Solution");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(frameWidth, frameHeight);
frame.addMouseListener(this);
frame.setLayout(null);
int i;
for(i = 1; i < width - 1; ++i) {
for(int j = 1; j < height - 1; ++j) {
grid[i][j] = new Grid();
grid[i][j].addMouseListener(this);
frame.add(grid[i][j]);
grid[i][j].setBounds(sideLength * i, sideLength * j, sideLength, sideLength);
}
}
for(i = 1; i < width - 1; ++i) {
grid[0][i] = new Grid(i);
frame.add(grid[0][i]);
grid[0][i].setBounds(sideLength * i, 0, sideLength, sideLength);
grid[height - 1][i] = new Grid(i);
frame.add(grid[height - 1][i]);
grid[height - 1][i].setBounds(sideLength * i, sideLength * (height - 1), sideLength, sideLength);
}
for(i = 1; i < height - 1; ++i) {
grid[i][0] = new Grid(i);
frame.add(grid[i][0]);
grid[i][0].setBounds(0, sideLength * i, sideLength, sideLength);
grid[i][width - 1] = new Grid(i);
frame.add(grid[i][width - 1]);
grid[i][width - 1].setBounds(sideLength * (width - 1), sideLength * i, sideLength, sideLength);
}
JLabel start0 = new JLabel("enter:");
frame.add(start0);
start0.setBounds(0, sideLength * height, 40, 40);
this.start1 = new JTextField();
frame.add(this.start1);
this.start1.setBounds(40, sideLength * height, 60, 40);
JLabel end0 = new JLabel("exit:");
frame.add(end0);
end0.setBounds(100, sideLength * height, 40, 40);
this.end1 = new JTextField();
frame.add(this.end1);
this.end1.setBounds(140, sideLength * height, 60, 40);
JButton mark = new JButton("mark");
frame.add(mark);
mark.setBounds(sideLength * width - 210, sideLength * height, 70, 40);
mark.addActionListener(new Maze.MarkListener());
JButton find = new JButton("find");
frame.add(find);
find.setBounds(sideLength * width - 140, sideLength * height, 70, 40);
find.addActionListener(new Maze.FindListener());
JButton retry = new JButton("retry");
frame.add(retry);
retry.setBounds(sideLength * width - 70, sideLength * height, 70, 40);
retry.addActionListener(new Maze.RetryListener());
JLabel label = new JLabel("");
frame.add(label);
label.setBounds(0, sideLength * (height + 1), sideLength, sideLength);
this.out = new JTextField();
frame.add(this.out);
this.out.setBounds(0, sideLength * (height + 1), frameWidth - 20, 40);
}
private int[] intOfStr(String str) {
int[] result = new int[2];
int index = str.indexOf(44);
result[0] = Integer.parseInt(str.substring(1, index));
result[1] = Integer.parseInt(str.substring(index + 1, str.length() - 1));
return result;
}
private boolean isfit(int i, int standard) {
return i > 0 && i < standard;
}
private static boolean findPath() {
path = new MyMaze();
Position[] offset = new Position[]{new Position(1, 0), new Position(0, 1), new Position(-1, 0), new Position(0, -1)};
Position current = start;
grid[current.x][current.y].isWall = true;
int option = 0;
int lastOption = 3;
float red = 0.0F;
float green = 1.0F - red;
while(current.x != end.x || current.y != end.y) {
int gridX = 0;
int gridY;
for(gridY = 0; option <= lastOption; ++option) {
gridX = current.x + offset[option].x;
gridY = current.y + offset[option].y;
if (!grid[gridX][gridY].isWall) {
break;
}
}
if (option <= lastOption) {
path.push(current);
grid[current.x][current.y].setBackground(new Color(red, green, 0.0F, 1.0F));
red += 0.035F;
if (red >= 1.0F) {
red = 1.0F;
green = 1.0F - red;
}
current = new Position(gridX, gridY);
grid[current.x][current.y].isWall = true;
option = 0;
} else {
if (path.isEmpty()) {
return false;
}
Position next = path.pop();
grid[next.x][next.y].setBackground(Color.WHITE);
if (next.y == current.y) {
option = 2 + next.x - current.x;
} else {
option = (3 + next.y - current.y) % 3;
}
current = next;
}
}
return true;
}
public static void main(String[] args) {
new Maze(9, 9);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
if (this.isMousePressed) {
if (e.getComponent().getBackground() == Color.BLACK) {
e.getComponent().setBackground(Color.WHITE);
} else if (e.getComponent().getBackground() == Color.WHITE) {
e.getComponent().setBackground(Color.BLACK);
}
}
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
this.isMousePressed = true;
if (e.getComponent().getBackground() == Color.BLACK) {
e.getComponent().setBackground(Color.WHITE);
} else if (e.getComponent().getBackground() == Color.WHITE) {
e.getComponent().setBackground(Color.BLACK);
}
}
public void mouseReleased(MouseEvent e) {
this.isMousePressed = false;
}
class FindListener implements ActionListener {
FindListener() {
}
public void actionPerformed(ActionEvent arg0) {
for(int i = 1; i < Maze.WIDTH - 1; ++i) {
for(int j = 1; j < Maze.HEIGHT - 1; ++j) {
if (Maze.grid[i][j].getBackground() == Color.BLACK) {
Maze.grid[i][j].setWall();
}
}
}
if (!Maze.findPath()) {
Maze.this.out.setText("i cannot find the way");
} else {
Maze.this.out.setText("success");
}
}
}
class MarkListener implements ActionListener {
MarkListener() {
}
public void actionPerformed(ActionEvent arg0) {
String str1 = Maze.this.start1.getText();
String str2 = Maze.this.end1.getText();
int startX = Maze.this.intOfStr(str1)[0];
int startY = Maze.this.intOfStr(str1)[1];
if (!Maze.this.isfit(startX, Maze.WIDTH - 1)) {
Maze.this.out.setText("未找到该点");
} else if (!Maze.this.isfit(startY, Maze.HEIGHT - 1)) {
Maze.this.out.setText("未找到该点");
} else {
Maze.start = new Position(startX, startY);
Maze.grid[startX][startY].isWall = false;
Maze.grid[startX][startY].setBackground(new Color(0.0F, 1.0F, 0.0F, 1.0F));
int endX = Maze.this.intOfStr(str2)[0];
int endY = Maze.this.intOfStr(str2)[1];
if (!Maze.this.isfit(endX, Maze.WIDTH - 1)) {
Maze.this.out.setText("未找到该点");
} else if (!Maze.this.isfit(endY, Maze.HEIGHT- 1)) {
Maze.this.out.setText("未找到该点");
} else {
Maze.end = new Position(endX, endY);
Maze.grid[endX][endY].isWall = false;
Maze.grid[endX][endY].setBackground(Color.RED);
}
}
}
}
class RetryListener implements ActionListener {
RetryListener() {
}
public void actionPerformed(ActionEvent arg0) {
for(int i = 1; i < Maze.WIDTH - 1; i++) {
for(int j = 1; j < Maze.HEIGHT - 1; j++ ) {
Maze.grid[i][j].isWall = false;
Maze.grid[i][j].setBackground(Color.WHITE);
Maze.this.start1.setText("");
Maze.this.end1.setText("");
Maze.this.out.setText("");
}
}
}
}
}
特别提醒:
源代码来源于网络,进行了学习与简单的修改,仅此记录本次学习内容,方便以后再次学习,若发现有侵权行为,请私信博主,进行删除,谢谢。