Java连连看课程设计_第1页
Java连连看课程设计_第2页
Java连连看课程设计_第3页
Java连连看课程设计_第4页
Java连连看课程设计_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 摘要 关键字:发展,关键字:发展,java,java,连连看,程序设计;连连看,程序设计; 现代科学技术的发展,改变了人类的生活,作为新世纪的大学生,应该站在时代发 展的前沿,掌握现代科学技术知识,以适应社会的发展,能够独立完成面临的任务, 作一名有创新意识的新型人才。 java 语言的学习热潮并没有因为时间的推移而消退,相反,由于计算机技术的发 展所带来的新应用的出现,java 越来越流行,这种情况是以往程序设计语言在其生存 周期内所不多见的。java 语言之所以这样长盛不衰,一是因为其众多的技术特点与现 今的应用十分合拍,可以覆盖大部分的需求;二是因为 sun 公司不断推出新的版本, 完

2、善 java 自身的功能。有了这两点,java 语言成为程序员首选的程序设计开发工具就 在情理之中了。 连连看游戏是一种很流行的小游戏,记得在小时候去游戏厅玩的时候就有两台专门 的连连看的机器(当然当时不叫这个名字),一个是连麻将牌、另一个是连水果图片。 当时的麻将牌分好几层,相邻层的牌还可以连,看得人眼花缭乱。作为一个 java 初学 者,我所编辑的“悠嘻猴连连看”小游戏,只有几个基本功能:“开始”“再来一局” 炸弹“重新开始”“退出”。我所选中给出的游戏界面很漂亮,不过似乎图形只有一 层,而且数量也不是很多,只有 64 张图,降低了不少难度。 目 录 摘要 .i 第 1 章 需求分析 .1

3、 1.1 功能分析 .1 1.2 流程图 .2 第 2 章 详细设计 .3 2.1 课程设计目的.3 2.2 课程设计的实验环境 .3 2.3 课程设计的预备知识 .3 2.4 课程设计要求 .3 2.5 连连看算法设计 .4 2.6 类的实现方法.4 2.6.1 成员变量 .4 2.6.2 方法设计 .5 第 3 章 测试分析 .7 3.1 程序运行情况.7 3.2 测试计划及分析.9 3.2.1 检验的先后顺序.9 3.2.2 程序异常处理.9 第 4 章 课程设计总结 .10 附件 a.1 参考资料 .26 第 1 章 需求分析 1.1 功能分析 每次用户选择两个图形,如果图形满足一定条

4、件(两个图形一样,且这两个图形之 间存在转弯少于 3 的路径) ,则两个图形都能消掉。给定任意具有相同图形的两个格子, 我们需要寻找这两个格子之间在转弯最少的情况下,经过格子数目最少的路径。如果 这个最优路径的转弯数目少于 3 ,则这两个格子可以消去。 将界面中相同的猴子图片消去,游戏限时 1000 秒,如果在规定的时间内没有完成, 就会跳出对话框“笨蛋!游戏时间到!game over !”的字样。如果玩家赢了这 局,还没有过瘾的话,可以单击“再来一局” 。判断游戏是否结束。如果所有图形全部 消去,或者游戏玩家不可能再消去任意两个格子的时候,游戏应该结束。后一种情况, 我们称之为“死锁” 。

5、在死锁的情况下,我们也可以暂时不终止游戏,而是随机打乱局面,使得打破“死 锁”局面。不管怎样,我们需要判别游戏当前状态是否为“死锁”状态。我们首先思 考问题:怎么判断两个图形能否相消?前面分析中,我们已经知道,两个图形能够相 消,当且仅当这两个图形相同,且它们之间存在路径转弯数目小于 3。 因此,我们主要需要解决的问题还是,怎样求出相同图形之间的最短路径?这个最 短的路径,我们首先需要保证转弯数目最少。在转弯数目最少的情况下,经过的格子 数目要尽可能地少。 在经典的最短路问题中,我们需要求出经过格子数目最少的路径。而这里,要保证 转弯数目最少,需要把最短路问题的目标函数修改为从一个点到另一个点

6、的转弯次数。 虽然,目标函数修改了,但算法的框架仍然可以保持不变。广度优先搜索是解决经典 最 短路问题的一个思路。我们看看在新的目标函数(转弯数目最少)下,如何用广度优 先搜索来解决图形 a(x1,y1)和图形 b(x2,y2)之间的最短路问题。 1.2 流程图 第 2 章 详细设计 2.1 课程设计目的 java 程序设计是计算机相关专业的必修专业基础课程,其实践性、应用性很 强。实践教学环节是必不可少的一个重要环节。本课程的程序设计专题实际是计算机 相关专业学生学习完java 程序设计课程后,进行的一次全面的综合训练,java 程 序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较

7、系统地掌握程序设 计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用 软件工程为基础进行软件开发、并在实践应用方面打下一定基础。 2.2 课程设计的实验环境 硬件要求能运行 windows 9.x 操作系统的微机系统。java 程序设计语言及相应的 集成开发环境,ultraedit-32 开发工具。 2.3 课程设计的预备知识 熟悉 java 语言及 ultraedit-32 开发工具。 2.4 课程设计要求 按课程设计指导书提供的课题,要求学生在自行完成各个操作环节,并能实现且达 到举一反三的目的,完成一个项目解决一类问题。要求学生能够全面、深入理解和熟 练掌握所学内

8、容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌 握,能够进行简单分析和判断;能编写出具有良好风格的程序;掌握 java 程序设计的 基本技能和面向对象的概念和方法;了解多线程、安全和网络等编程技术。同时培养 学生进行分析问题、解决问题的能力;培养学生进行设计分析、设计方法、设计操作 与测试、设计过程的观察、理解和归纳能力的提高。 2.5 连连看算法设计 在检验两个方块能否消掉的时候,我们要让两个方块同时满足两个条件才行,就 是两者配对并且连线成功。 * 分 3 种情况:(从下面的这三种情况,我们可以知道,需要三个检测,这三个 检测分别检测一条直路经。这样就会有三条路经。若这三条

9、路经上都是空按钮,那么 就刚好是三种直线(两个转弯点)把两个按钮连接起来了) * 1.相邻 * 2. 若不相邻的先在第一个按钮的同行找一个空按钮。1).找到后看第二个按钮 横向到这个空按钮所在的列是否有按钮。2).没有的话再看第一个按钮到与它同行的那 个空按钮之间是否有按钮。3).没有的话,再从与第一个按钮同行的那个空按钮竖向到 与第二个按钮的同行看是否有按钮。没有的话路经就通了,可以消了. * 3.若 2 失败后,再在第一个按钮的同列找一个空按钮。1).找到后看第二个按 钮竖向到这个空按钮所在的行是否有按钮 2).没有的话,再看第一个按钮到与它同列 的那个空按钮之间是否有按钮。3).没有的话

10、,再从与第一个按钮同列的那个空按钮横 向到与第二个按钮同列看是否有按钮。没有的话路经就通了,可以消了。 * 若以上三步都失败,说明这两个按钮不可以消去。 2.6 类的实现方法 2.6.1 成员变量 成员变量也叫类的属性,一般带有访问控制属性的,而全局变量虽然也有类的属 性,但全局变量严重影响了封装和模块化,一般的全局变量前面要加上 static 和 fina 属性其中,static 使该变量任何类都可用(方法 classname.全局变量名) ,而 fina 则使得变量不可更改,基本上算是常量了,这也在一定程度上防止对变量的非法 修改。 表 2-6-1 成员变量 成员变量描述变量类型名称 文件

11、 filefile 文件区 jtextareatextarea 菜单项 jmenuitemmenuitem_copy 菜单 umenuitemumenuitem 标签 jlabellabel_seek 文件名 stringseel 2.6.2 方法设计 方法名称为任何合乎语法的识别字,返回值类型是方法执行结果返回给调用者的 数据类型,void 表示没有返回值,参数行(parameter list)是调用时给予的参数声明, 两个以上的参数声明以逗号隔开,若没有参数则参数行为空白,调用时每一个参数对 应一个参数值(argument)大括号内为方法本体,也称为方法程序模块(block),包含声 明(

12、declarations)和语句(statements),声明也可以掺杂在语句之间。一个方法不能 声明在另一个方法内。 表 2-6-2 方法定义 方法名功能备注 mytexteditor 创建文本编辑器构造方法 dialog 创建对话框 addmenu 添加菜单栏菜单项 writetofile 向文本区写文件 readfromfile 读文件 opendialog 打开文件 savedialog 保存对话框 actionperformed 事件处理 itemstatechanged itemlistener 事件处理方法 mouseclicked 鼠标处理事件接口方法 mouseevent 鼠

13、标处理事件接口方法 mousereleased 鼠标处理事件接口方法 mouseentered 鼠标处理事件接口方法 mouseexit 鼠标处理事件接口方法 mousedragged 鼠标处理事件接口方法 main 程序开始运行 第 3 章 测试分析 3.1 程序运行情况 连连看游戏规则很简单,就是点中两个互相匹配并且可以通过不多于两个折点的 折线连在一起的方块后,这两个方块就可以消掉。 图 1 初始界面 菜单选项中,包括“开始游戏”、“重新开始”、“炸弹”、“退出”功能。 当选择炸弹功能时:每次含有三个炸弹,所炸的位置也是随机的; 图 2 游戏界面 粗略想来,由于用户每次只能消除一对图形,

14、即只会用到一个最短路径,但由于 实现并不知道用户会选择哪一对图形,所以需要事先计算出所有可能的最短路径并保 存起来。此外,采用这种方法的话似乎每次用户消去一对相同图像之后都需要重新计 算出当前所有可能被连接的相同图形之间最短路径,这是因为当某些图像被消去之后 可能会产生很多新路径,而我们又不能确定这些空出来的格子到底能够影响哪些路径, 所以就只好都重新计算一遍。其缺点很明显就是每次消去图形动作之后重新计算所有 可能的最短路径所需要消耗的时间;而该方法的优点则是可以很快地判断两个相同图 形之间是否存在满足条件的最短路径。 如果用户很厉害,每次都能选中可以消除的图形对,那么用这种方法浪费的时间 就

15、会相当可观,毕竟用户未选中的其他可以连接的图形对之间的最短路径都被浪费掉 了;而如果用户很差劲,每轮选择的次数都远远大于当前可能的连接数量时,该方法 就会比书中正文提到的方法高效。但这种情况是比较少的,因为在整个游戏中用户主 要是会用眼睛“找”而不是频繁的用鼠标去“试” 。所以总的来看,维护所有最短路径 的方法的效率相对比较低。游戏结束后,在页面出现对话框,询问玩家是否进行下一 局。 3.2 测试计划及分析 3.2.1 检验的先后顺序 在检验两个方块能否消掉的时候,我们要让两个方块同时满足两个条件才行,就 是两者配对并且连线成功。所以,这里应该先检验配对,如果该条件不成立的话,就 不要再进行连

16、线检查了,这样可以避免很多不必要的复杂运算。当然,如果你在做这 个游戏的时候,配对规则不够如此简单的话,那么就看哪个算起来麻烦就把它放在后 面。 3.2.2 程序异常处理 本程序没有涉及到程序的异常处理,只有关于“死锁”问题,本质上还是判别两个 格子是否可以消去的问题。最直接的方法就是,对于游戏中尚未消去的格子,两两都 计算一下,它们是否可以消去。此外,从上面的广度优先搜索可以看出,我们每次都 是扩展出起始格子 a(x1,y1)能够到达的格子。也就是说,对于每一个格子,我们可以 调用一次上面的扩展过程,得到所有可以到达的格子,如果这些格子中有任意一个跟 起始格子的图形一致,则它们可以消去,目前

17、游戏还不是“死锁”状态。 第 4 章 课程设计总结 通过这次课程设计还使我懂得了理论与实际相结合是很重要的,只有理论知识是 远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真 正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇 到问题,可以说得是困难重重,并且还发现了自己的许多不足之处,对以前所学过的 知识理解得不够深刻,掌握得不够牢固。但通过这次课程设计之后,一定把以前所学 过的知识重新温故。 我完成了这次 java 课程设计,不过这只是我学习路上的驿站。我相信我在未来的 学习中会记住从本次课程设计中所学到的东西,并将它用到未来的学习中去。在这

18、里 谢谢老师的指导,我会更加努力的学习 附件 a * * 类名: mainframe * 作用: 自定义主类,对鼠标拖拽的初始界面进行声明* * 继承的父类: jframe 类 * * 实现的接口: strings* * import java.awt.*; import javax.swing.*; import cn.elva.settings; import cn.elva.model.map; public class mainframe extends jframe private static final long serialversionuid = 1l; /炸弹的次数 pri

19、vate int bombcount = settings.bombcount; private jpanel jcontentpane = null; private jmenubar menubar = null; private jmenu filemenu = null; private jmenuitem reloaditem = null; private jmenuitem startitem = null; /炸弹 private jmenuitem bombitem = null; private jmenuitem exititem = null; private mapu

20、i mapui = null; / 游戏开始时间 private long starttime; / 结束时间 private long endtime; private timer timer = null; / private jmenuitem ti private jmenubar initmenubar() if (menubar = null) menubar = new jmenubar(); filemenu = new jmenu(菜单); startitem = new jmenuitem(开始游戏); startitem.addactionlistener(new act

21、ionlistener() public void actionperformed(actionevent e) reload(); ); reloaditem = new jmenuitem(重新开始); reloaditem.addactionlistener(new actionlistener() public void actionperformed(actionevent e) reload(); ); bombitem = new jmenuitem(炸弹); bombitem.addactionlistener(new actionlistener() public void

22、actionperformed( actionevent e ) if( bombcount=0 ) joptionpane.showmessagedialog(mainframe.this,三枚 炸弹已用完! ); bombitem.setenabled(false); return; mapui.bomb(); bombcount-; ); exititem = new jmenuitem(退出); exititem.addactionlistener(new actionlistener() public void actionperformed(actionevent e) syste

23、m.exit(0); ); filemenu.add(startitem); filemenu.add(reloaditem); filemenu.add( bombitem ); filemenu.add(exititem); menubar.add(filemenu); return menubar; public static void main(string args) / 自动生成方法存根 swingutilities.invokelater(new runnable() public void run() mainframe thisclass = new mainframe();

24、 thisclass.setdefaultcloseoperation(jframe.exit_on_close); thisclass.setvisible(true); ); public mainframe() super(); initialize(); private void initialize() this.setsize(650, 650); this.settitle(llk); this.setjmenubar(initmenubar(); this.settitle(悠嘻猴连连看); private void reload() mapui = new mapui();

25、starttime = system.currenttimemillis() / 1000; endtime = starttime + settings.pertime; jcontentpane = new jpanel(); jcontentpane.setlayout(new borderlayout(); jcontentpane.add(mapui); this.setcontentpane(jcontentpane); this.validate(); map.leftcount = settings.rows * settings.columns; inittimer(); b

26、ombitem.setenabled(true); bombcount=settings.bombcount; private void inittimer() actionlistener actionlistener = new actionlistener() public void actionperformed(actionevent e) starttime = system.currenttimemillis() / 1000; if (starttime = endtime) joptionpane.showmessagedialog(mainframe.this, 笨蛋!时

27、间到! game over!); int result = joptionpane.showconfirmdialog(mainframe.this, 重玩一次?, again, joptionpane.yes_no_cancel_option); if (result = joptionpane.yes_option) reload(); else jcontentpane.setvisible(false); validate(); ; timer = new javax.swing.timer(1000, actionlistener); timer.start(); * * 类名: m

28、apui * 作用: 定义按钮和炸弹功能* * 继承的父类: jpanel 类 * * 实现的接口: stings * * import java.awt.*; import javax.swing.*; import cn.elva.settings; import cn.elva.model.arraypoint; import cn.elva.model.map; public class mapui extends jpanel implements actionlistener private static final long serialversionuid = 1l; / 棋子

29、数组,用按钮来表示 private chessbutton chesses = null; / 数据模型 private map map = new map(); / 判断当前点击的棋子是否是第二次选中的 private boolean two = false; / 前面点的那个棋子 private arraypoint priviouspoint; / 第二次选中的棋子 private arraypoint currpoint; / 构造函数 public mapui() super(); initialize(); / 初始化函数 private void initialize() ini

30、tchesses(); gridlayout gridlayout = new gridlayout(settings.rows + 2, settings.columns + 2); gridlayout.sethgap(2); gridlayout.setvgap(2); this.setlayout(gridlayout); this.setsize(300, 200); / 放置按钮,按行 for (int row = 0; row settings.rows + 2; row+) for (int col = 0; col settings.columns + 2; col+) ad

31、d(chessesrow * (settings.columns + 2) + col); private void initchesses() int values = map.getmap(); / 初始化棋子,和数据模型里保持一样 this.chesses = new chessbutton(settings.rows + 2) * (settings.columns + 2); for (int row = 0; row 10; row+) for (int col = 0; col 10; col+) / 通过二维的数据模型坐标得到一维的棋子坐标 int index = row *

32、(settings.columns + 2) + col; / 对棋子的数据模型,即 arraypoint 对象进行设置,指定此棋子 具体的位置和值 chessesindex = new chessbutton(row, col, valuesrowcol); / 添加监听器 chessesindex.addactionlistener(this); / 将外围的一圈设为不可见,行,列为 0 和为最大值的情况 if (row = 0 | row = (settings.rows + 2 - 1) | col = 0 | col = (settings.columns + 2 - 1) ches

33、sesindex.setvisible(false); public void clearcheese(arraypoint priviouspoint, arraypoint currpoint) / 处理匹配,看两点是否联通 int values = map.getmap(); / 将模型中对应的棋子设为 0 valuespriviouspoint.geti()priviouspoint.getj() = 0; valuescurrpoint.geti()currpoint.getj() = 0; / 使两个已经消除的按钮不可见 int index1 = priviouspoint.get

34、i() * (settings.columns + 2) + priviouspoint.getj(); int index2 = currpoint.geti() * (settings.columns + 2) + currpoint.getj(); chessesindex1.setvisible(false); chessesindex2.setvisible(false); / 如果棋子总数已为 0,则程序结束 if (map.leftcount = 0) joptionpane.showmessagedialog(this, 恭喜您通过!); /* * 事件监听器处理函数,也是处理

35、棋子消除的地方 */ public void actionperformed(actionevent e) / 获得当前的柜子 chessbutton button = (chessbutton) e.getsource(); / 获得当前棋子的数据结构 arraypoint p = button.getpoint(); / 如果已有两个棋子选中, 则进行判断操作 if (two) currpoint = p; if( map.match(this.priviouspoint, this.currpoint) clearcheese(this.priviouspoint, this.currp

36、oint); / 设置为没有两个按钮的选中的状态 two = false; else / 将当前点击的棋子赋给变量 priviouspoint this.priviouspoint = p; / 标志位设为 true,用于点击下个棋子的时候使用 two = true; /炸弹的功能 public void bomb() int values = map.getmap(); arraypoint p1 = null; arraypoint p2 = null; for (int row = 1; row settings.rows + 1; row+) for (int col = 1; col

37、 settings.columns + 1; col+) if (valuesrowcol != 0) p1 = new arraypoint(row, col, valuesrowcol); for (int i = 1; i settings.rows + 1; i+) for (int j = 1; j settings.columns + 1; j+) if (valuesij != 0) p2 = new arraypoint(i, j, valuesij); else continue; if (map.match(p1, p2) clearcheese(p1, p2); retu

38、rn; * * 类名: chessbutton * 作用: 初始化游戏中鼠标点击按钮* * 继承的父类: jbutton 类 * * 实现的接口: 没有 * * import .*; import javax.swing.*; import cn.elva.settings; import cn.elva.model.arraypoint; public class chessbutton extends jbutton protected arraypoint point = null; public chessbutton(int row, int col, int value) this

39、(new arraypoint(row, col, value); public chessbutton(arraypoint point) this.point = point; string name =resource/+point.getvalue() + settings.relex; url url = chessbutton.class.getresource(name); imageicon icon = new imageicon( url ); this.seticon(icon); /构造函数,使用默认值 public chessbutton() this(new arr

40、aypoint(0, 0, 0); /返回当前按钮代表的位置和值 public arraypoint getpoint() return point; public void setpoint(arraypoint point) this.point = point; * * 接口名:settings* * 作用: 声明各个变量大小* * package cn.elva; public interface settings /行数 public static final int rows = 8; /列数 public static final int columns=8; /图片后缀名 pu

41、blic static final string relex=.gif; /每局所花时间(秒) public static final int pertime = 600; /判断的时间间隔 public static final int per = 1; /炸弹的使用次数 public static final int bombcount = 3; * * 类名: map * 作用: 连入图片并声明游戏规则* * package cn.elva.model; import java.util.random; import cn.elva.settings; public class map

42、public static int leftcount = settings.rows * settings.columns; / 让其最外层的数据不显示,可以解决边框消除不掉的情况 private int map = new intsettings.rows + 2settings.columns + 2; / 出现的不同图片个数 private int maxkinds = 4; public map() init(); public int getmap() return map; private void init() int temparr = new intsettings.row

43、s * settings.columns; int len = temparr.length; / 根据图片的种类数来确定数组大小,如有 64 张图片,每四个为一样的, 则需要图片数为 64/4=16 for (int i = 0; i len / maxkinds; i+) temparri * 4 = i + 1; temparri * 4 + 1 = i + 1; temparri * 4 + 2 = i + 1; temparri * 4 + 3 = i + 1; / 打乱一维数组内数据的排列 random(temparr); / 填充到二维数组中 for (int i = 1; i

44、settings.rows + 1; i+) for (int j = 1; j 0; i-) int j = random.nextint(i); int temp = arrayi - 1; arrayi - 1 = arrayj; arrayj = temp; /* * 判断是否在一条直线上,这里不去比较两者值是否相等,主要用于后面 两个拐点的情况 * p1 之前的点 * p2 当前所点的点 * true 相通,false 不通 */ public boolean onelinewithoutvalue(arraypoint p1, arraypoint p2) if (horizonm

45、atch(p1, p2) return true; else if (verticalmatch(p1, p2) return true; return false; /* * 判断是否在一条直线上,其中包括了垂直和水平两种情况 * p1 之前的点 * p2 当前所点的点 * true 相通,false 不通 */ public boolean oneline(arraypoint p1, arraypoint p2) if (p1.value != p2.value) return false; if (onelinewithoutvalue(p1, p2) return true; return false; /* * 竖线上的判断 * p1 之前的点 * p2 当前所点的点 * true 相通,false 不通 */ public boolean verticalmatch(arraypoint p1, arraypoint p2) if (p1.j != p2.j) return false; if (p1.i p2.i) arraypoint temp = null; temp = p1; p1 = p2; p2 = temp; / 之间的相隔的棋子数 int spacecount = p2.i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论