Maze
此项目已打包为 exe 文件,电脑有 gre 即可下载运行 download先看效果图
直接上代码啦
- 启动游戏单独成类
package MyMaze;
public class Maze {
public static void main(String[] args) {
// 启动迷宫游戏
new Figure().init();
}
}
- 保存迷宫每一个格子的信息
package MyMaze;
/**
* 本类保存迷宫中每一个格子的信息
*/
public class Place {
//定义当前格子是否可走,若 wall → 0,则表示可走,若 wall → 1,则表示不可走
private int wall;
//表示当前格子是否被搜索过
private boolean search = false;
//表示当前格子的四个方向分别是哪些格子,搜索时的上一个格子。
private Place east = null, south = null, west = null, north = null, last = null;
//保存迷宫格子位置索引
private int index = 0;
public Place(int wall) {
this.wall = wall;
}
public int getWall() {
return wall;
}
public void setWall(int wall) {
this.wall = wall;
}
public boolean isSearch() {
return search;
}
public void setSearch(boolean search) {
this.search = search;
}
public Place getEast() {
return east;
}
public void setEast(Place east) {
this.east = east;
}
public Place getSouth() {
return south;
}
public void setSouth(Place south) {
this.south = south;
}
public Place getWest() {
return west;
}
public void setWest(Place west) {
this.west = west;
}
public Place getNorth() {
return north;
}
public void setNorth(Place north) {
this.north = north;
}
public Place getLast() {
return last;
}
public void setLast(Place last) {
this.last = last;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
- 创建迷宫
package MyMaze;
/**
* 创建迷宫及提供迷宫的一些参数
*/
public class CreateMaze {
// 定义迷宫规模
private int size;
// 定义迷宫的入口和出口
private int entrance, exit;
// 用一维数组表示迷宫,0 号下标位置空出
private Place[] maze = null;
// 设置迷宫中每一个格子下一步能移动的方向
private void setDirections(Place[] maze) {
for (int i = 1; i <= size * size; i++) {
if (i % size != 0 && maze[i + 1].getWall() == 0 && maze[i + 1] != null) {
maze[i].setEast(maze[i + 1]);
}
if (i <= size * (size - 1) && maze[i + size].getWall() == 0 && maze[i + size] != null) {
maze[i].setSouth(maze[i + size]);
}
if (i % size != 1 && maze[i - 1].getWall() == 0 && maze[i - 1] != null) {
maze[i].setWest(maze[i - 1]);
}
if (i > size && maze[i - size].getWall() == 0 && maze[i - size] != null) {
maze[i].setNorth(maze[i - size]);
}
}
}
// 设置默认迷宫参数
public CreateMaze() {
this.size = 10;
this.entrance = 1;
this.exit = this.size * this.size;
}
// 调用有参构造函数获取新迷宫大小及入口和出口
public CreateMaze(int size, int entrance, int exit) {
this.size = size;
this.entrance = entrance;
this.exit = exit;
}
// 返回当前迷宫格随机状态
public Place[] getMaze() {
maze = new Place[size * size + 1];
for (int i = 1; i <= size * size; i++) {
maze[i] = new Place((int) (Math.random() * 2));
maze[i].setIndex(i); // 设为 0 或 1
}
setDirections(maze);
return maze;
}
// 返回入口索引
public int getEntrance() {
return entrance;
}
// 设置入口索引
public void setEntrance(int entrance) {
this.entrance = entrance;
}
// 返回出口索引
public int getExit() {
return exit;
}
// 设置出口索引
public void setExit(int exit) {
this.exit = exit;
}
// 返回迷宫大小 size 表示边长
public int getSize() {
return size;
}
// 设置迷宫边长
public void setSize(int size) {
this.size = size;
}
}
- 对迷宫路径进行搜索
package MyMaze;
/**
* 迷宫游戏
* 本类中对迷宫进行路径搜索,保存合格迷宫的相关信息(合格迷宫只有1条路径)
*/
public class Path {
//调用创建迷宫类
CreateMaze newMaze;
//保存迷宫路径
boolean[] path;
//保存合格迷宫
Place[] maze = null;
// 入口位置索引
int entrance;
// 出口位置索引
int exit;
private int searchPathNumber() {
// 获取当前格状态
maze = newMaze.getMaze();
// 定义路径数
int pathAll = 0;
// 保存当前路径
Place[][] path = new Place[maze.length][];
for (int i = 1; i < path.length; i++) {
path[i] = new Place[5];
}
// 当前格子路径数组下标
int pathTop = 0;
// 当前位置的下一位置的可能数下标
int[] top = new int[maze.length];
for (int i = 1; i < top.length; i++) {
top[i] = -1;
}
//寻找迷宫路径数
if (maze[entrance].getWall() == 0) {
pathTop++;
top[pathTop]++;
path[pathTop][top[pathTop]] = maze[entrance];
while (pathTop > 0) {
//判断当前位置是否为结束位置,是,保存迷宫路径,退回上一位置,否,寻找下一不重复位置
if (path[pathTop][0] == maze[exit]) {
pathAll++;
top[pathTop]--;
pathTop--;
} else if (!path[pathTop][top[0]].isSearch()) {
//寻找当前位置的下一位置的可能数
if (path[pathTop][0].getEast() != null && path[pathTop][0].getEast() != path[pathTop][0].getLast() && !path[pathTop][0].getEast().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getEast();
}
if (path[pathTop][0].getSouth() != null && path[pathTop][0].getSouth() != path[pathTop][0].getLast() && !path[pathTop][0].getSouth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getSouth();
}
if (path[pathTop][0].getWest() != null && path[pathTop][0].getWest() != path[pathTop][0].getLast() && !path[pathTop][0].getWest().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getWest();
}
if (path[pathTop][0].getNorth() != null && path[pathTop][0].getNorth() != path[pathTop][0].getLast() && !path[pathTop][0].getNorth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getNorth();
}
path[pathTop][0].setSearch(true);
}
//当前位置的下一位置的所有可能依次查询,无下一位置则回退到上一位置
if (top[pathTop] == 0) {
path[pathTop][0].setLast(null);
path[pathTop][0].setSearch(false);
top[pathTop]--;
pathTop--;
}
else {
pathTop++;
top[pathTop]++;
path[pathTop][0] = path[pathTop - 1][top[pathTop - 1]--];
path[pathTop][0].setLast(path[pathTop - 1][0]);
}
}
}
return pathAll;
}
// 设置路径
private void setPath() {
// 保存当前路径
Place[][] path = new Place[maze.length][];
for (int i = 1; i < path.length; i++) {
path[i] = new Place[5];
}
// 当前路径数组下标
int pathTop = 0;
// 当前位置的下一位置的可能数下标
int[] top = new int[maze.length];
for (int i = 1; i < top.length; i++) {
top[i] = -1;
}
//寻找迷宫路径数
if (maze[entrance].getWall() == 0) {
pathTop++;
top[pathTop]++;
path[pathTop][top[pathTop]] = maze[entrance];
while (pathTop > 0) {
//判断当前位置是否为结束位置,是,保存迷宫路径,退回上一位置,否,寻找下一不重复位置
if (path[pathTop][0] == maze[exit]) {
for (int i = 1; i <= pathTop; i++) {
this.path[path[i][0].getIndex()] = true;
}
top[pathTop]--;
pathTop--;
break;
} else if (!path[pathTop][top[0]].isSearch()) {
//寻找当前位置的下一位置的可能数
if (path[pathTop][0].getEast() != null && path[pathTop][0].getEast() != path[pathTop][0].getLast() && !path[pathTop][0].getEast().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getEast();
}
if (path[pathTop][0].getSouth() != null && path[pathTop][0].getSouth() != path[pathTop][0].getLast() && !path[pathTop][0].getSouth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getSouth();
}
if (path[pathTop][0].getWest() != null && path[pathTop][0].getWest() != path[pathTop][0].getLast() && !path[pathTop][0].getWest().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getWest();
}
if (path[pathTop][0].getNorth() != null && path[pathTop][0].getNorth() != path[pathTop][0].getLast() && !path[pathTop][0].getNorth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getNorth();
}
path[pathTop][0].setSearch(true);
}
//当前位置的下一位置的所有可能依次查询,无下一位置则回退到上一位置
if (top[pathTop] == 0) {
path[pathTop][0].setLast(null);
path[pathTop][0].setSearch(false);
top[pathTop]--;
pathTop--;
} else {
pathTop++;
top[pathTop]++;
path[pathTop][0] = path[pathTop - 1][top[pathTop - 1]--];
path[pathTop][0].setLast(path[pathTop - 1][0]);
}
}
}
}
// 当路径唯一时,设置路径
private void searchPath() {
while (true) {
if (searchPathNumber() == 1) {
setPath();
break;
}
}
}
// 默认构造函数
public Path() {
newMaze = new CreateMaze();
path = new boolean[newMaze.getSize() * newMaze.getSize() + 1];
this.entrance = newMaze.getEntrance();
this.exit = newMaze.getExit();
}
// 重载构造函数
public Path(int size, int entrance, int exit) {
newMaze = new CreateMaze(size, entrance, exit);
path = new boolean[newMaze.getSize() * newMaze.getSize() + 1];
this.entrance = newMaze.getEntrance();
this.exit = newMaze.getExit();
}
// 获取当前格子
public Place[] getMaze() {
searchPath();
return maze;
}
// 获取新迷宫大小
public int getSize() {
return newMaze.getSize();
}
// 获取入口
public int getEntrance() {
return entrance;
}
// 获取出口
public int getExit() {
return exit;
}
// 返回当前格子为路还是墙
public boolean[] getPath() {
return path;
}
// 返回迷宫
public CreateMaze getNewMaze() {
return newMaze;
}
}
- 构建图形界面
package MyMaze;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* 本类为迷宫游戏提供图形化界面
*/
public class Figure {
// 定义路径
Path path;
// 定义当前迷宫周围状态
Place[] maze = null;
// 用按钮实现迷宫格
JButton[] button = null;
boolean[] isPath = null;
// A* 寻路界面 比较遗憾的是只实现了图形化界面,A* 自动寻路并未实现,有机会有能力再更吧
class FindMaze extends JFrame implements ActionListener {
public FindMaze() {
super("A* Maze");
// 界面大小
this.setSize(500, 500);
// 返回默认工具箱
Toolkit kit = Toolkit.getDefaultToolkit();
// 获取屏幕尺寸
Dimension screenSize = kit.getScreenSize();
// 获取屏幕宽度
int screenWidth = screenSize.width;
// 获取屏幕高度
int screenHeight = screenSize.height;
// 获取界面窗口宽度
int windowWidth = this.getWidth();
// 获取界面窗口高度
int windowHeight = this.getHeight();
// 界面居中
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 四行一列布局
this.setLayout(new GridLayout(path.getSize(), path.getSize()));
maze = path.getMaze();
int entrance = path.getEntrance();
int exit = path.getExit();
button = new JButton[maze.length];
for (int i = 1; i < maze.length; ++i) {
// 当前格子是路则设置活动指令为 1,背景颜色为绿色
if (maze[i].getWall() == 0) {
button[i] = new JButton();
button[i].setActionCommand("1");
button[i].setBackground(Color.GREEN);
}
// 当前格子为墙则设置活动指令为 0,标记为灰色
if (maze[i].getWall() == 1) {
button[i] = new JButton();
button[i].setActionCommand("0");
button[i].setBackground(Color.LIGHT_GRAY);
}
}
for (int i = 1; i < button.length; i++) {
button[i].addActionListener(this);
add(button[i]);
}
button[path.getSize() * path.getSize()].setActionCommand("退出");
button[path.getSize() * path.getSize()].setText("退出");
button[path.getSize() * path.getSize()].setFont(new Font("宋体", 0, 7));
addWindowListener(new closeWin());
this.setVisible(true);
}
// 自动寻路
public void innit() {
isPath = path.getPath();
for (int i = 1; i < isPath.length; i++) {
if (isPath[i]) {
button[i].setBackground(Color.YELLOW);
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("退出")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
// 启动游戏界面
class MazeGameFigure extends JFrame implements ActionListener {
public MazeGameFigure() {
super("迷宫游戏");
}
public void init() {
// 界面大小
this.setSize(500, 500);
// 返回默认工具箱
Toolkit kit = Toolkit.getDefaultToolkit();
// 获取屏幕尺寸
Dimension screenSize = kit.getScreenSize();
// 获取屏幕宽度
int screenWidth = screenSize.width;
// 获取屏幕高度
int screenHeight = screenSize.height;
// 获取界面窗口宽度
int windowWidth = this.getWidth();
// 获取界面窗口高度
int windowHeight = this.getHeight();
// 界面居中
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 四行一列布局
this.setLayout(new GridLayout(5, 1));
JLabel welcom = new JLabel("欢迎进入迷宫游戏!");
welcom.setBackground(Color.CYAN);
welcom.setFont(new Font("宋体", 1, 25));
JButton find = new JButton("A* 寻路");
find.setFont(new Font("宋体", 1, 25));
JButton start = new JButton("开始游戏");
start.setFont(new Font("宋体", 1, 25));
JButton set = new JButton("游戏设置");
set.setFont(new Font("宋体", 1, 25));
JButton end = new JButton("退出游戏");
end.setFont(new Font("宋体", 1, 25));
find.setBackground(Color.PINK);
start.setBackground(Color.PINK);
set.setBackground(Color.PINK);
end.setBackground(Color.PINK);
add(welcom);
add(find);
add(start);
add(set);
add(end);
find.addActionListener(this);
start.addActionListener(this);
set.addActionListener(this);
end.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("A* 寻路")) {
dispose();
new FindMaze().innit();
}
// 点击开始游戏生成迷宫
if (e.getActionCommand().equals("开始游戏")) {
MazeFigure mazeFigure = new MazeFigure();
mazeFigure.init();
dispose();
}
// 点击游戏设置进入设置模式
if (e.getActionCommand().equals("游戏设置")) {
MazeSetFigure mazeSetFigure = new MazeSetFigure();
mazeSetFigure.init();
dispose();
}
if (e.getActionCommand().equals("退出游戏")) {
dispose();
}
}
}
// 开始游戏界面
class MazeFigure extends JFrame implements ActionListener {
public MazeFigure() {
super("Maze");
}
public void init() {
this.setSize(500, 500);
this.setBackground(Color.BLACK);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 获取迷宫尺寸设计按钮布局
this.setLayout(new GridLayout(path.getSize(), path.getSize()));
maze = path.getMaze();
int entrance = path.getEntrance();
int exit = path.getExit();
button = new JButton[maze.length];
for (int i = 1; i < maze.length; i++) {
// 当前格子是路则设置活动指令为 1,背景颜色为绿色
if (maze[i].getWall() == 0) {
button[i] = new JButton();
button[i].setActionCommand("1");
button[i].setBackground(Color.GREEN);
}
// 当前格子为墙则设置活动指令为 0,标记为灰色
if (maze[i].getWall() == 1) {
button[i] = new JButton();
button[i].setActionCommand("0");
button[i].setBackground(Color.LIGHT_GRAY);
}
}
button[entrance].setText("入口");
button[entrance].setFont(new Font("宋体", 1, 7));
button[exit].setText("出口");
button[exit].setFont(new Font("宋体", 1, 7));
// 为每个按钮添加监听器
for (int i = 1; i < button.length; i++) {
button[i].addActionListener(this);
add(button[i]);
}
addWindowListener(new closeWin());
this.setVisible(true);
}
// 判断是否完成通路
private boolean isComplete() {
isPath = path.getPath();
for (int i = 1; i < isPath.length; i++) {
if (isPath[i] && button[i].getBackground() != Color.YELLOW) {
return false;
}
}
return true;
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.getActionCommand().equals("1")) {
if (button.getBackground() == Color.GREEN) {
button.setBackground(Color.YELLOW);
} else if (button.getBackground() == Color.YELLOW) {
button.setBackground(Color.GREEN);
}
}
if (isComplete()) {
CongratulationFigure congratulationFigure = new CongratulationFigure();
congratulationFigure.init();
this.dispose();
}
}
}
// 迷宫设置界面
class MazeSetFigure extends Frame implements ActionListener, TextListener {
String newSize, newEntrance, newExit;
JTextField setMaze, setEntrance, setExit;
int size, entrance, exit;
public MazeSetFigure() {
super("迷宫设置");
}
public void init() {
this.setSize(500, 400);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
GridLayout layout = new GridLayout(5, 2);
this.setLayout(layout);
JLabel size = new JLabel("迷宫规模");
size.setFont(new Font("宋体", 1, 20));
JLabel entrance = new JLabel("迷宫入口");
entrance.setFont(new Font("宋体", 1, 20));
JLabel exit = new JLabel("迷宫出口");
exit.setFont(new Font("宋体", 1, 20));
JButton menu = new JButton("返回菜单");
menu.setFont(new Font("宋体", 1, 20));
JButton set = new JButton("设置完成");
set.setFont(new Font("宋体", 1, 20));
setMaze = new JTextField("10");
setEntrance = new JTextField("左上角");
setEntrance.setFont(new Font("宋体", 1, 18));
setExit = new JTextField("右下角");
setExit.setFont(new Font("宋体", 1, 18));
JLabel tip = new JLabel("tips:出入口只能设置为四个角");
JLabel tips = new JLabel("即左上角,右上角,左下角,右下角");
add(tip);
add(tips);
add(size);
add(setMaze);
add(entrance);
add(setEntrance);
add(exit);
add(setExit);
add(menu);
add(set);
menu.addActionListener(this);
set.addActionListener(this);
setMaze.addActionListener(this);
setEntrance.addActionListener(this);
setExit.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("返回菜单")) {
dispose();
Figure figure = new Figure();
figure.init();
}
if (e.getActionCommand().equals("设置完成")) {
boolean isSizeReasonable = true;
boolean isEntranceReasonable = true;
boolean isExitReasonable = true;
newSize = setMaze.getText();
newEntrance = setEntrance.getText();
newExit = setExit.getText();
try {
size = Integer.parseInt(newSize);
} catch (Exception ex) {
isSizeReasonable = false;
}
if (isSizeReasonable == true) {
if (newEntrance.equals("左上角")) {
entrance = 1;
} else if (newEntrance.equals("右上角")) {
entrance = size;
} else if (newEntrance.equals("左下角")) {
entrance = size * (size - 1) + 1;
} else if (newEntrance.equals("右下角")) {
entrance = size * size;
} else {
isEntranceReasonable = false;
}
if (newExit.equals("左上角")) {
exit = 1;
} else if (newExit.equals("右上角")) {
exit = size;
} else if (newExit.equals("左下角")) {
exit = size * (size - 1) + 1;
} else if (newExit.equals("右下角")) {
exit = size * size;
} else {
isExitReasonable = false;
}
if (isEntranceReasonable == true && isExitReasonable == true) {
if (entrance == exit) {
isEntranceReasonable = false;
isExitReasonable = false;
}
}
}
if (isSizeReasonable == true && isEntranceReasonable == true && isExitReasonable == true) {
dispose();
Figure figure = new Figure(size, entrance, exit);
figure.init();
} else {
SetErrorFigure setErrorFigure = new SetErrorFigure();
setErrorFigure.init();
dispose();
}
}
}
public void textValueChanged(TextEvent e) {
}
}
// 通过迷宫游戏界面
class CongratulationFigure extends Frame implements ActionListener {
public CongratulationFigure() {
super("恭喜");
}
public void init() {
this.setSize(220, 200);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
this.setLayout(new GridLayout(2, 1));
JLabel text = new JLabel("恭喜您成功走出迷宫!");
JButton button = new JButton("确认");
button.setBackground(Color.WHITE);
add(text);
add(button);
button.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("确认")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
// 游戏设置数据错误界面
class SetErrorFigure extends Frame implements ActionListener {
public SetErrorFigure() {
super("错误");
}
public void init() {
this.setSize(230, 100);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
this.setLayout(new GridLayout(2, 1));
JLabel text = new JLabel("您输入的数据不合理,设置失败!");
JButton button = new JButton("确认");
button.setBackground(Color.WHITE);
add(text);
add(button);
button.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("确认")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
class closeWin extends WindowAdapter {
public void windowClosing(WindowEvent e) {
Window w = e.getWindow();
w.dispose();
}
}
public Figure() {
path = new Path();
}
public Figure(int size, int entrance, int exit) {
path = new Path(size, entrance, exit);
}
public void init() {
MazeGameFigure mazeGameFigure = new MazeGameFigure();
mazeGameFigure.init();
}
}