目录
1.系统简介
1.1设计背景
1.2开发工具及环境
2.系统分析与设计
2.1设计目的
2.2功能需求
2.3系统功能代码设计
2.3.1算法说明
3.系统调试
3.1编写源程序界面
4.设计总结
附录:源代码
1.系统简介
1.1设计背景
迷宫是一个经典的游戏,陪伴了几代人的童年,借此机会,在锻炼自身编程水平的同时还原这一经典游戏。
1.2开发工具及环境
(1)开发工具及介绍
IntelliJ IDEA2021是一款专业的JAVA IDE编程工具,最新版本支持git、svn、github等版本控制工具,并整合了智能代码助手、代码自动提示等功能,软件的强大的静态代码分析和人体工程学设计,能够让用户的开发设计变得简单轻松。同时,它也被认为是当前Java开发效率最快的IDE工具。
(2)开发环境:window10系统、IntelliJ IDEA2021、JDK17。
2.系统分析与设计
2.1设计目的
随机生成迷宫并且尝试用两种方法生成迷宫和解迷宫,支持玩家走迷宫和系统走迷宫,玩家走迷宫需通过键盘方向键控制;系统走迷宫需要输出走到迷宫出口的最优解。
2.2功能需求
(1)迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;
(2)要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫。
(3)要求迷宫游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,输出玩家当前位置到迷宫出口的最优路径。设计交互友好的游戏图形界面。
2.3系统功能代码设计
2.3.1算法说明
主要思路是从图中一个未访问的顶点 V 开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底…,不断递归重复此过程,直到所有的顶点都遍历完成,它的特点是不撞南墙不回头,先走完一条路,再换一条路继续走。
树是图的一种特例(连通无环的图就是树),接下来我们来看看树用深度优先遍历该怎么遍历。
1、我们从根节点 1 开始遍历,它相邻的节点有 2,3,4,先遍历节点 2,再遍历 2 的子节点 5,然后再遍历 5 的子节点 9。
2、上图中一条路已经走到底了(9是叶子节点,再无可遍历的节点),此时就从 9 回退到上一个节点 5,看下节点 5 是否还有除 9 以外的节点,没有继续回退到 2,2 也没有除 5 以外的节点,回退到 1,1 有除 2 以外的节点 3,所以从节点 3 开始进行深度优先遍历,如下:
3、同理从 10 开始往上回溯到 6, 6 没有除 10 以外的子节点,再往上回溯,发现 3 有除 6 以外的子点 7,所以此时会遍历 7。
3、从 7 往上回溯到 3, 1,发现 1 还有节点 4 未遍历,所以此时沿着 4, 8 进行遍历,这样就遍历完成了。
完整的节点的遍历顺序如下(节点上的的蓝色数字代表):
相信大家看到以上的遍历不难发现这就是树的前序遍历,实际上不管是前序遍历,还是中序遍历,亦或是后序遍历,都属于深度优先遍历。
那么深度优先遍历该怎么实现呢,有递归和非递归两种表现形式,接下来我们以二叉树为例来看下如何分别用递归和非递归来实现深度优先遍历。
递归实现
递归实现比较简单,由于是前序遍历,所以我们依次遍历当前节点,左节点,右节点即可,对于左右节点来说,依次遍历它们的左右节点即可,依此不断递归下去,直到叶节点(递归终止条件)。
3.系统调试
3.1编写源程序界面
4.设计总结
迷宫这个项目十分有趣,但也特别的难,我虽然看懂了算法,但 还是无法用于自己的程序当中,在这次实习项目的练习过程中,认识到了自己的不足。代码量太少,再加之这个项目的难度较大,所以还是无法独立完成,在于同学的讨论和上 搜寻下才勉强完成这个项目,在这次软件 实习的过程中,认识到了自己的不足和代码水平,在今后的学习生活 中会加强训练,提升自己的代码水平。
附录:源代码
-
package 迷宫;
-
-
import java.awt.Color;
-
import java.awt.Graphics;
-
import java.awt.event.KeyAdapter;
-
import java.awt.event.KeyEvent;
-
import java.util.Random;
-
import java.util.Stack;
-
import javax.swing.JFrame;
-
import javax.swing.JOptionPane;
-
import javax.swing.JPanel;
-
- // 格子
-
class Lattice {
- static final int InTree = 1;
- static final int NotInTree = 0;
- private final int x; // 格子的位置,在第几行
- private final int y; // 第几列
- private int flag = NotInTree; // flag,标识格子是否已加入树中
- private Lattice father = null; // 格子的父亲节点
-
- public Lattice(int a, int b) {
- x = a;
- y = b;
- }
-
- public int getX() {
- return x;
- }
-
- public int getY() {
- return y;
- }
-
- public int getFlag() {
- return flag;
- }
-
- public Lattice getFather() {
- return father;
- }
-
- public void setFather(Lattice dad) {
- father = dad;
- }
-
- public void setFlag(int f) {
- flag = f;
- }
-
- public String toString() {
- return "(" + x + "," + y + ")n";
- }
- }
-
-
class Labyrinth extends JPanel {
- private final int num;// num:迷宫大小;
- private final int width;//width:每个格子的宽度和高度
- private final int padding;
- private final Lattice[][] maze;
- private int ball_X, ball_Y; // 球的位置,在第几行第几列格子上
- private boolean drawPath = false; // flag,标识是否画出路径
-
- Labyrinth(int n, int w, int p) {
- num = n;
- width = w;
- padding = p;
- maze = new Lattice[num][num];
- for (int i = 0; i 1; i++)
- for (int j = 0; j 1; j++)
- maze[i][j] = new Lattice(i, j);
- createMaze();
- setKeyListener();
- this.setFocusable(true);
- }
-
- // 初始化游戏,重开一局时使用
- private void init() {
- for (int i = 0; i 1; i++)
- for (int j = 0; j 1; j++) {
- maze[i][j].setFather(null);
- maze[i][j].setFlag(Lattice.NotInTree);
- }
- ball_X = 0;
- ball_Y = 0;
- drawPath = false;
- createMaze();
- // setKeyListener();
- this.setFocusable(true);
- repaint();
- }
-
- // 由格子的行数,得到格子中心点的像素X座标
- public int getCenterX(int x) {
- return padding + x * width + width / 2;
- }
-
- // 由格子的列数,得到格子中心点的像素Y座标
- public int getCenterY(int y) {
-
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!