收藏 分享(赏)

实验4-迷宫-电子版.doc

上传人:hskm5268 文档编号:8838815 上传时间:2019-07-14 格式:DOC 页数:30 大小:2.29MB
下载 相关 举报
实验4-迷宫-电子版.doc_第1页
第1页 / 共30页
实验4-迷宫-电子版.doc_第2页
第2页 / 共30页
实验4-迷宫-电子版.doc_第3页
第3页 / 共30页
实验4-迷宫-电子版.doc_第4页
第4页 / 共30页
实验4-迷宫-电子版.doc_第5页
第5页 / 共30页
点击查看更多>>
资源描述

1、云南大学软件学院 2009 级网络工程http:/ 1(本实验项目方案受“教育部人才培养模式创新实验区(X3108005 ) ”项目资助)实验难度: A B C 序号 学号 姓名 成绩1 20091120XXX 罗 X2 20091120XXX 吴 X3指导教师 (签名)学 期: 2010 秋季学期 任课教师: 实验题目: 迷宫 小 组 长: 联系电话: 电子邮件: 完成提交时间: 2010 年 12 月 12 日云南大学软件学院 数据结构实验报告云南大学软件学院 2009 级网络工程http:/ 2云南大学软件学院 2010 学年 秋季 学期数据结构实验成绩考核表学号: 2009112005

2、1 姓名: 吴 X 本人承担角色:UNION/FIND 算法实现评分项目 评分指标 分值 得分1. 实验目的明确 5实验构思(10% ) 2. 实验内容理解透彻、对实验所涉及到的知识点分析到位51. 有对基本数据结构的抽象数据类型定义52. 实验方案设计完整,数据结构、算法选择合理 5实验设计(15% )3.算法结构和程序功能模块之间逻辑清晰、有相应的流程图51. 代码编写规范、风格统一、注释清楚易读 52. 程序运行正常,测试结果正确 15实验实现(25% )3. 界面友好、易于操作、有较强的容错性51. 内容详实无缺漏,文字流畅、图表清楚5实验报告撰写(10% )2. 实验结果分析客观、详

3、细,实验体会真实可信,对原实验方案的改进和对实验内容的发散性思考51. 个人完成工作量 152. 个人技术水平 10个人工作量(30% )3. 团队合作精神 51. 有一定用户群 5实验运作(10% ) 2. 应用前景分析 5综合得分: (满分 100 分)指导教师: 年 月 日(注:此表在难度为 C 时使用,每个成员一份。 )云南大学软件学院 2009 级网络工程http:/ 3云南大学软件学院 2010 学年 秋季 学期数据结构实验成绩考核表学号: 20091120073 姓名: 罗 X 本人承担角色:绘图,以及整合代码评分项目 评分指标 分值 得分1. 实验目的明确 5实验构思(10%

4、) 2. 实验内容理解透彻、对实验所涉及到的知识点分析到位51. 有对基本数据结构的抽象数据类型定义52. 实验方案设计完整,数据结构、算法选择合理 5实验设计(15% )3.算法结构和程序功能模块之间逻辑清晰、有相应的流程图51. 代码编写规范、风格统一、注释清楚易读 52. 程序运行正常,测试结果正确 15实验实现(25% )3. 界面友好、易于操作、有较强的容错性51. 内容详实无缺漏,文字流畅、图表清楚5实验报告撰写(10% )2. 实验结果分析客观、详细,实验体会真实可信,对原实验方案的改进和对实验内容的发散性思考51. 个人完成工作量 152. 个人技术水平 10个人工作量(30%

5、 )3. 团队合作精神 51. 有一定用户群 5实验运作(10% ) 2. 应用前景分析 5综合得分: (满分 100 分)指导教师: 年 月 日(注:此表在难度为 C 时使用,每个成员一份。 )云南大学软件学院 2009 级网络工程http:/ 4(下面的内容由学生填写,格式统一为,字体: 楷体, 行距: 固定行距 18,字号: 小四,个人报告按下面每一项的百分比打分。难度 A 满分 70 分,难度 B 满分 90 分)一、 【实验构思(Conceive ) 】(10%)(本部分应包括:描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计、算法等相关知识) 。 基本思路:首先在迷

6、宫中主要有 4 种状态要确定好,一个是入口,一个是出口,一个 是通路,一个是墙。总的来说涉及两个概念,一个是可以通过,一个是不可以通过。但是我们要在面板上表示出这两种状态是有选择的,一个可以创建对象,一个是可以通过绘图,而绘图的话效率更高。 程序设计:贯彻设计程序所必需的五大步骤,即目标分析设计算法程序编写后期调试软件维护。 算法设计:算法满足有穷性、确定性、可行性,有 0 个或多个输入,有多个输出。并且具备了正确性、健壮性和可读性的特征。 设计迷宫游戏,首先想到要重载面板的绘图方法,这样才能画出迷宫,其次,为了增加难度,玩家将无法看到迷宫全景,只能看到视野范围内的物体。不过为了方便测试,我们

7、要求程序把生成的迷宫图输出到控制台中。 为增加趣味性,可以随机生成迷宫道具,而且可以设置不同道具的生成概率,使玩家可以使用道具改变视野、寻路、拆墙等。 要使用户可以随意定义迷宫的维数,而且二、 【实验设计(Design)】(20%)(本部分应包括:抽象数据类型的功能规格说明、主程序模块、各子程序模块的伪码说明,主程序模块与各子程序模块间的调用关系)2.1 数据结构抽象数据类型。这次实验在生成迷宫时主要使用到 union/find 算法,方法与不相交集类 ADT 描述如下:public class DisjoinSets /* 创建不相交类对象* param numElements 如果调用成功

8、的不相交集的初始数目*/public int s;public DisjoinSets(int numElements )s = new intnumElements;for( int i = 0; i| i=0,1,n-1操作集合:(1) public DisjoinSets(int numElements ) 构造器,初始化(2) public void union(int root1,int root2) 并操作连接两个节点(3) public int find( int x ) 查找根节点,并返回 ADT DisjoinSets 2.2 主程序模块MainFrameMainFrame

9、模块主要用于生成迷宫的 GUI 界面。核心算法的伪码描述如下:实例化 GUI 控件,包括菜单栏、 迷宫画布和状态栏。将 GUI 控件添加至主程序窗口。添加键盘动作监听器处理用户按下上下左右方向键要激活的动作。添加菜单事件监听器处理用户点击菜单项要激活的动作。2.1.1 MainFrame 内部模块键盘事件监听器/* 处理键盘事件* param evt 事件名*/private void formKeyPressed(KeyEvent evt, Maze maze)/* mazeMap 为画布的 GUI,调用的方法返回人物在迷宫中的坐标数组的引用*/int location = mazeMap.

10、getRoleLocation();switch(evt.getKeyCode()/得到用户按键的虚拟键盘编码case KeyEvent.VK_LEFT: /如果是左方向键if( location0=1 mazeMap.setDirection(JPanelMaze.EAST);/将人物方向设置为向左云南大学软件学院 2009 级网络工程http:/ 6mazeMap.repaint(); /重绘画布statusLabel.setText(“您已到达迷宫入口,休想溜走! “);/设置状态栏文字break;/退出else if(mazeMap.move(evt)/否则调用画布的移动方法 move

11、,若前方不为墙,则产生人物移动效果statusLabel.setText(“向左一步,当前坐标:(“+ (location0) +“,“+ (location1)+“)“ );else /若 move 方法返回 false(即前方为墙) ,则设置状态栏文字提醒.statusLabel.setText(“前方为墙,不可通过!当前坐标:(“+ location0 +“,“+ location1+“)“);break;case KeyEvent.VK_UP:/若按向上方向键if( mazeMap.move(evt) )statusLabel.setText(“向上一步,当前坐标:(“+ (locat

12、ion0)+“,“+location1+“)“ );elsestatusLabel.setText(“前方为墙,不可通过!当前坐标:(“+ location0 +“,“+ location1+“)“);break;case KeyEvent.VK_RIGHT:if( location0=mazeMap.getMapRows()-2 mazeMap.setDirection(JPanelMaze.EAST);mazeMap.repaint();statusLabel.setText(“您已成功走出迷宫!“);/设置状态栏提醒用户走出迷宫JOptionPane.showMessageDialog(

13、this, “恭喜您成功走出迷宫!“,“恭喜!“,JOptionPane.INFORMATION_MESSAGE);/弹出对话框提示用户走出迷宫break;else if( mazeMap.move(evt) )statusLabel.setText(“向右一步,当前坐标:(“+ (location0) +“,“+ (location1)+“)“ );else statusLabel.setText(“前方为墙, 不可通过! 当前坐标:(“+ location0 +“,“+ location1+“)“);break;case KeyEvent.VK_DOWN:if( mazeMap.move(

14、evt) )statusLabel.setText(“向下一步,当前坐标:(“+ (location0)+“,“+location1+“)“ );elsestatusLabel.setText(“前方为墙,不可通过!当前坐标:(“+ location0 +“,“+ location1+“)“);break;2.1.2 MainFrame 内部模块游戏菜单事件监听器/内部类用来新建迷宫class NewGameActionListener implements ActionListener/实现监听器类int rows = frameWidth, height = frameHeight;pub

15、lic NewGameActionListener(int width, int height)super();this.rows = width;this.height = height;Override/* 处理新建游戏菜单事件* param e 事件名* param mapWidth 生成新地图的宽度(非迷宫宽度)* param mapHeight 生成新地图的高度*/public void actionPerformed(ActionEvent e)/* 生成迷宫并传递给面板*/maze = new Maze( (rows-1)/2, (height-1)/2); /生成新的迷宫maz

16、eMap.gainMaze(maze); /调用画布的 gainMaze 方法得到迷宫的引用并重绘画布云南大学软件学院 2009 级网络工程http:/ 7 2.1.3 MainFrame 内部模块设置视野大小菜单监听器/内部类用来设置视野大小class HorizonActionListener implements ActionListenerint horizon;int width, height;/* 监听器的构造方法* param width 窗口宽度(像素)* param height 窗口高度* param horizon 画布人物视野(只能为 2、3、4,代表人物能看到的迷宫

17、格子半径范围)*/public HorizonActionListener(int width, int height, int horizon)super();this.width = width;this.height = height;this.horizon = horizon;Overridepublic void actionPerformed(ActionEvent e)mazeMap.setHorizon(horizon);/mazeMap.repaint();setSize(width, height);2.2 迷宫画布模块 JpanelMaze该模块继承了 javax.sw

18、ing 包中的 Jpanel,编程过程中覆盖了 Jpanel 的双缓冲绘图方法用于在面板上绘制迷宫。在主框架中他只有一个实例那便是 MazeMap。这个模块的绘图分为如下几个过程:1) 获得对迷宫 Maze 的一个实例的引用;2) 获取人物视野,从而得知面板上要显示的单元格数(如视野为 3 时显示 9 格,视野为 4 时显示 25 格) ;3) 设置画布背景,本程序中,使用大理石的纹理图片填充背景;4) 绘制墙壁,这是一个两层 for 循环的过程,将视野范围内的所有地图坐标均扫描一遍确定每个单元和其周围格子的状态(通路 or 墙):a) 因为地图是根据迷宫扩展而得(故地图的行和列分别等于迷宫的

19、行和列乘 2 加1).故当地图坐标全为奇数时,该点其实为迷宫中的一个房间,故该点必为通路,此时我们需要得到这个迷宫房间四面墙的状态,放入一个布尔数组wallStatus 中,并根据 wallStatus 数组设置面板上要绘制的邻居单元格的状态(存储到布尔数组 isRoad 中) ;b) 当地图坐标全为偶数时,该坐标反映在迷宫中其实是不存在的,是进行从迷宫到地图的扩展过程中必须存在的无用坐标,故该点必定为墙;c) 当地图坐标为一奇一偶时,该点其实是迷宫中某个房间的一面墙的状态。可直接访问 isRoad 数组得到其状态。云南大学软件学院 2009 级网络工程http:/ 85) 绘制人物。由于任务

20、会覆盖墙壁,故在最后绘制。人物始终保持在面板中央。而且人物有四个方向的状态。当按下方向键后,可以更改人物的方向。 JPanelMaze 内部动作事件模块move(处理键盘动作)/* 处理动作的方法* 需要用 switch 来判断那个键被按下,按下后按两种情况处理:下一个方位是路 or 是墙,* 若是路,改变坐标,重绘* 若是墙,则只改变人物方向,不产生移动。* param evt 传递的键盘事件* return 如果前方是墙, 则返回 false*/public boolean move(KeyEvent evt) int locationX = (isRoad.length - 1) / 2

21、;/得到屏幕中央人物的 isRoad 坐标int locationY = (isRoad0.length - 1) / 2;/得到屏幕中央人物的 isRoad 坐标switch (evt.getKeyCode() case KeyEvent.VK_LEFT:direction = WEST;/改变人物方向if (isRoadlocationXlocationY - 1) /如果左边是通路,已排除到达入口的情况roleLocation1-;repaint();return true;/前方是墙repaint();return false;case KeyEvent.VK_UP:direction

22、 = NORTH;if (isRoadlocationX - 1locationY) roleLocation0-;repaint();return true;repaint();return false;case KeyEvent.VK_RIGHT:direction = EAST;if (isRoadlocationXlocationY + 1) roleLocation1+;repaint();return true;repaint();return false;case KeyEvent.VK_DOWN:direction = SOUTH;if (isRoadlocationX + 1

23、locationY) roleLocation0+;repaint();return true;repaint();return false;return true;/防止编译错误2.3 生成迷宫模块 Maze可以根据给定的行数和列数生成一个迷宫。迷宫核心算法采用了合并不相交集类的思想。云南大学软件学院 2009 级网络工程http:/ 9迷宫的格式为行*列个迷宫格子(用一个一维对象数组保存每个格子,再用一个一维数组表示这些格子和其他格子的连通状态,即保存着合并不相交集类产生的生成树) ,初始状态时格子的四面都是墙。然后随机选取一个迷宫格子和它的某个邻居格子使用合并不相交集类算法拆墙并得到一个

24、生成树,树的根节点保存着这棵树的深度的负数,每个叶子节点都保存着对树根的索引。这个算法的最终结果是遍历了所有的格子并且得到的只有一颗生成树。使得迷宫中所有格子都可以被访问而且存在通向出口的通路。2.4 迷宫单元模块 MazeRoom保存着一个迷宫格子四面墙的状态。2.5 不相交集类模块 DisjoinSets核心算法为合并算法 union 和 查找算法 find,详述请见后。2.6 道具面板模块 Tools由于开发时间限制,故没有开发出游戏中可以使用的道具。仅仅将用于改变主角视野的道具修改成菜单选项来实现。道具设计的有火把(有效时间内可以扩大视野至 3) 、照明弹(有效时间内可以扩大视野至4)

25、 、爬虫(从主角所在坐标开始查找到出口的通路) 、炸弹(可以炸开一面墙构造通路)等。三、 【实现描述(Implement ) 】(30%)(本部分应包括:抽象数据类型具体实现的函数原型说明、关键操作实现的伪码算法、 函数设计、函数间的调用关系,关键的程序流程图等,给出关键算法的时间复杂度分析。 )并查集:(union-find sets)是一种简单的用途广泛的集合.并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多。一般采取树形结构来存储并查集,并利用一个 s数组来存储集合的深度下界,在查找操作时进行路径压缩使后续的查找操作加速。这样优化实现的并查集,空间复杂度为

26、O(N),建立一个集合的时间复杂度为 O(1),N 次合并 M 查找的时间复杂度为 O(M Alpha(N)(Alpha(n)=mink|Ackerman(k)=n。即Alpha(n)是使 n parentj,则让 j 成为 i 的双亲,否则,让 i 成为 j 的双亲。此即 Union 的加权规则。parent0(= -4) parent4 (= -3)public void union(int root1,int root2)/改进算法,不是直接进行合并云南大学软件学院 2009 级网络工程http:/ 12if( find(root1)=find(root2) /root1中结点数多sfi

27、nd(root1) +=sfind(root2);sfind(root2) = (root1);else /root2中结点数多sfind(root2)+=sfind(root1);sfind(root1) = (root2);使用加权规则得到的树四、 【测试结果(Testing) 】(10%)(本部分应包括:对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析总结) 初始状态云南大学软件学院 2009 级网络工程http:/ 13 生成简单难度的迷宫(包含控制台迷宫)云南大学软件学院 2009 级网络工程http:/ 14 生成中等难度的迷宫(包含控制台输出)

28、云南大学软件学院 2009 级网络工程http:/ 15 生成令人发狂难度的迷宫 生成自定义维数的迷宫(迷宫较大时,时间复杂度瓶颈越明显)云南大学软件学院 2009 级网络工程http:/ 16 调整视野为最大视野云南大学软件学院 2009 级网络工程http:/ 17 调整视野为二倍视野云南大学软件学院 2009 级网络工程http:/ 18 调整视野为正常视野云南大学软件学院 2009 级网络工程http:/ 19 帮助菜单与关于菜单 开始走迷宫(以二倍视野演示向左、向右、向上、向下、回到入口、到达出口)云南大学软件学院 2009 级网络工程http:/ 20向左不可通过时云南大学软件学院

29、 2009 级网络工程http:/ 21左移一步云南大学软件学院 2009 级网络工程http:/ 22向右不可通过时云南大学软件学院 2009 级网络工程http:/ 23右移一步云南大学软件学院 2009 级网络工程http:/ 24向上不可通过云南大学软件学院 2009 级网络工程http:/ 25向上一步云南大学软件学院 2009 级网络工程http:/ 26向下一步云南大学软件学院 2009 级网络工程http:/ 27向下不可通过云南大学软件学院 2009 级网络工程http:/ 28返回入口时云南大学软件学院 2009 级网络工程http:/ 29走出迷宫时五、 【实验总结】(1

30、0%)(本部分应包括:自己在实验中完成的任务,注意组内的任意一位同学都必须独立完成至少一项接口的实现;对所完成实验的经验总结、心得)吴 X:在这次实验中我们首次尝试通过分工,独立完成实现某些功能的算法,在这次我们把整个项目分为了两个方向,一个是迷宫的生成,一个是迷宫的绘图。因为之前有了解到两种迷宫的表示方法,一个是产生 N*N 的对象,一个是通过创建面板控制器来自己绘图。这两种效率明显不一样,而且空间的占用率也不同,绘图对于创立对象更加高效,但是没有接触过,所以从头来学,这块由罗 X 负责。我在这次试验中,主要负责迷宫的生成。而在迷宫生成中,主要也有两种方法,一种是通过上述的不想交集合来实现,

31、通过随机选取“墙”来创建迷宫,而例外一种是通过图的遍历来实现。这两种方法中我选择了前者,个人认为不相交集的方法更加巧妙。而在实现过程中,开始我在每个 MazeBox 中建立了两面墙,因为开始认为所有 MazeBox中只要有两面墙就能构成整个迷宫,没有把集合的自反性考虑进去,而且每个 MazeBox 每次只能在两面墙中选择一面,所以虽然是随机的但是生成的时候还是比较规则的达不到希望的效果,而且在每个 MazeBox 只能向下一个或者右边走,但是实际中我们可能在迷宫中走回头云南大学软件学院 2009 级网络工程http:/ 30路,所以最后还是选择了 4 面墙。还有一个问题就是产生随机数,当迷宫规

32、模为 N*N 时,且N 比较大时,所产生的随机数就比较慢,因为最后所有数都指向同一个根节点,所以耗时大,效率低,然后就通过改进随机数的产生来提高效率。罗 X:这一次实验我的主要任务是绘图的实现,因此用了较多准备时间用来学习 Java 的 2D 绘图。虽然走了不少弯路,原地转了好几圈,但通过不断地摸索和查阅资料,最终还是明白了Java 的绘图原理,知道应该怎样达到自己预期的绘图效果。为了节约设计的时间,迷宫游戏的背景、墙壁和人物模型全部为 2D 的,而且全部为使用现成的图片加工所得,没有过多的使用 Java 2D API 来绘制图形。经过不断的调试,绘图这一关总算过了,接下来的工作便是建立迷宫与

33、面板画布的关联,使得我可以访问迷宫中的每个单元来完成我的绘图。首先想到吴润设计的迷宫表示方式是每个房间四面墙,只有房间有坐标;而真正生成的画布应该是不论是墙还是房间都有坐标。于是第一步就是完成坐标的转换。假如生成了一个 5*8 的迷宫,那么反映到面板绘出的迷宫中就应该是(2*5+1)*(2*8+1)的大小。这样,迷宫中的房间反映到绘出的地图中行和列坐标将都为奇数。而每个房间的四面墙的坐标自然是房间的相邻坐标(行和列坐标一奇一偶或一偶一奇) ,而行和列都是偶数坐标是没有对应的迷宫映射的,即为永不可达点,全部为墙。完成了迷宫到地图的映射,下一步要完成的就是键盘动作的处理,这一步比较简单,只需要在主

34、框架中添加一个键盘动作监听器和一个对应的方法(采用内部类的形式) ,每个方法里在调用 JpanelMaze 实例中的公共方法 move 就可以完成了。在这一次实验里收获还是很大的。对软件的开发也有了更深入的了解。六、 【项目运作描述(Operate) 】(10%)(本部分应包括:项目的成本效益分析,应用效果等的分析。 )这是一款真正可玩的迷宫游戏,玩家可以通过调整迷宫的大小和视野的大小改变游戏难度。而且本游戏有一个特色功能,即可以把迷宫输出到控制台中。故玩家只要在控制台中运行该程序就可以看到迷宫的全貌。游戏的视觉体验还有待加强,可能会造成墙动人不动的感觉。玩家按上下左右四个方向键时,游戏中的人物也就是仙剑奇侠传 98 柔情版中的李逍遥会呈现四个方向的效果。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报