




免费预览已结束,剩余18页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
跳棋程序源码下载源代码 作者:俞尚 大小:2.7M 发布日期:2006-09-08 浏览:206 电脑智能升级难度更大, 采用隔空跳的规则,这样变化更多一些,可玩性更好, 是一个eclipse的工程, 现在是最新版本: 1.修改电脑的智力,难度更高,要战胜电脑?你有10%的机会 2.现在支持多个玩家游戏(将来支持网络游戏) 3.下一步设想移植到手机,PPC上;4.增加声音效果;“我的跳棋”设计说明书,作者:俞尚来自:/user17/yushang0824/blog/26621680.html.一、概述: 跳棋在我国是一项老少皆宜、流传广泛的益智型棋类游戏。由于其规则简单,一玩就懂,一辈子都不会忘,所以几乎每个人从小到大都下过跳棋。如果您不愿陷入激烈的思考和竞争,那么无疑本游戏可以使您回到一种更平和、产生美好回忆的心情之中。 在此我把近十天的成果做一个简要的介绍,尽量把问题说得清楚细致。希望与对跳棋编程有同样兴趣的伙伴们好好讨论一下,也希望下一版本的跳棋做得更好。 这个跳棋游戏主要有下几个特点:界面漂亮,操作简单,功能简洁,老少兼宜。我爸爸都很喜欢下。整个跳棋的源码你可以下载。二、跳棋整体设计UML类图:先给跳棋整个代码做一个整体介绍,说明每个包,每个类具体作用:1.org.yushang.jumpchess.appAppJumpChess.java实现的漂亮的窗体界面,标题栏和各种按钮,设置玩家个数及类型(人,或是计算机)。2.org.yushang.jumpchess.audioWavePlayer.java主要用于播放游戏中各种声音效果,比较简单。3.org.yushang.jumpchess.imageImageLoader.java主要用于从资源文件中导入各种图片背景,比较简单。4.org.yushang.jumpchess.InterfaceAnimation.java是用于播放动画的超类lAnimationGO.java是用于播放棋子走动的动画lAnimationSelect.java是用于播放棋子被选中后,“抖动”动画效果lDrawer.java主要是静态地显示棋盘、棋子、下棋位置等图片lJumpChessControl.java是一个很复杂的类,控制玩家下棋顺序、棋子棋盘的显示、动画显示、以及响应玩家的下棋的鼠标事件。.yushang.jumpchess.pkgChess.java棋子类,说明棋子的颜色以及索引号等信息。lChessBoard.java棋盘类:l 索引功能:为棋子和棋盘坐标建立索引关系,根据棋子的可快速检索出该棋子的坐标或根据坐标快速检索出该位置是否有棋子。由于这两项功能在下棋过程中使用频率很高,因此对性能要求也很高。 下棋规则:设定了下棋规则,可以是传统的规则,也可以隔空跳规则。这是一个麻烦的工作。涉及数据结构方面的知识,有图的生成和最短路径搜索两个难点。 RealChessBoard和VirtualChessBoard是ChessBoard派生类: RealChessBoard中建立了棋子和棋盘坐标建立真正的索引关系。而VirtualChessBoard是建立在RealChessBoard基础之上的,VirtualChessBoard只是保存当已走动的棋子坐标变化情况,这样VirtualChessBoard的数据量很小,提高计算机下棋智能计算速度,这一优点在介绍计算机下棋策略详细讨论。RealChessBoard和VirtualChessBoard只是创建方式有点区别,使用上没有任何差别,这也是多态性的一个运用。Player.java玩家类l保存了玩家棋子颜色、昵称、敌对玩家,棋子摆放初始区域等信息。同时输出下棋路径,为播放动画作准备。有两个Play和Man两个派生类,计算机玩家的下棋由org.yushang.jumpchess.strategy控制,而人玩家的下棋要由用户鼠标事件来驱动。这两个类实现这两个不同的功能。6.org.yushang.jumpchess.pubBoardArea.java这把棋盘各玩家所处的位置编号成6个区域。该类可得到自己区域包含哪些坐标(getAreaPositions)。也可得到和自己相对区域(getOppsiteArea)。lColor.java是棋子颜色类lDirector.java棋盘任何一坐标位置(非棋盘边界),在放六个方向上都有相邻的坐标位置,lMap.java、Node.java、Nodes.java三个文件是和数据结构“图”相关的三个类。lPosition.java棋盘坐标类,有三个功能:设定了棋盘边界、给定一方向可以得到该方向上相邻的坐标、计算与另一坐标的距离。.yushang.jumpchess.strategy计算机下棋策略主要有以下几个方面: 计算出己方所有可能走法 选出一个跳得最远(尽快让自己获胜)的棋子和走法。 选择一个最可能阻碍对方前行的棋子和走法。 尽可能选择可为下一步提供最有利条件的棋子和走法 对以上几项做综合分析,得出较好的走法。 Analyser.java:策略分析类,运用对各种策略进行综合分析, 得出较好的下棋位置。Strategy.java:策略基类。MainStrategy.java:让棋子跳得最远的策略DoubleStrategy.java: 为下一步提供最有利条件的策略OppsiteScore.java:尽可能阻碍对方前行的策略三、界面设计: 因为这是一个游戏,应该在界面上下点功夫,早就不是DOS时代了,应该不会有人喜欢玩一个界面很难看的游戏。同时界面要简洁,功能也不必太多,但基本功能却一定要做好,让用户玩得痛快。下图是界面:界面看起来很复杂其实很简单,棋盘是图片,按钮也是图片,都是贴上去的。这里有两个难点:1.标题栏制作:l去掉原有的标题栏:创建Shell的时候加上SWT.NO_TRIM参数就没有边框和标题栏了sShell = new Shell(SWT.NO_TRIM);l生成自己的标题栏创建一个Label,放到Shell的(0,0)位置,设置一下图片就可以了Title.jpg是一个图片: final ImageLoader imageTitle = new ImageLoader(sShell.getDisplay(), Title.jpg);/ ImageLoader是自己创建的类,用于载入Title.jpg,lblTitle = new Label(parent, SWT.NO_BACKGROUND);lblTitle.setImage(imageTitle.getImage();/设置Image属性lblTitle.setBounds(0, 0, 800, 28);/设置位置和大小l如何移动Shell 标题栏做好了,问题成于这个Label假标题栏无法移动Shell,怎么办呢?只要当鼠标在lblTitle上拖动时,程序就要调整Shell的位置,才能完成原有标题栏的效果。代码图如下:Static boolean mouseDown = false; /鼠标是否按下的标记Static Point lastMousePoint = null; /按下鼠标时的位置 lblTitle.addMouseListener(new MouseAdapter( /按下鼠标时 public void mouseDown(MouseEvent e) mouseDown = true; /设置按下标记 lastMousePoint = new Point(e.x, e.y); /记录按下的位置 /鼠标释放时 public void mouseUp(MouseEvent e) mouseDown = false; /清除按下标记 ); lblTitle.addMouseMoveListener(new MouseMoveListener() public void mouseMove(MouseEvent e) if (mouseDown) /鼠标在lblTitle上移动,且鼠标已按下 Point nowMousePoint = new Point(e.x, e.y);/鼠标的新位置 Point point = sShell.getLocation();/当前Shell的位置 /计算Shell的新位置 point.x += (nowMousePoint.x - lastMousePoint.x); point.y += (nowMousePoint.y - lastMousePoint.y); sShell.setLocation(point);/设置Shell的位置 ); 2.按钮制作:先导入三个按钮图片l正常显示的图片Begin1.jpg鼠标移动到按钮上时显示的图片Begin2.jpg按下鼠标时显示的图片Begin1.jpgfinal ImageLoader imageBegin1 = new ImageLoader(sShell.getDisplay(), Begin1.jpg);final ImageLoader imageBegin2 = new ImageLoader(sShell.getDisplay(), Begin2.jpg);final ImageLoader imageBegin3 = new ImageLoader(sShell.getDisplay(),Begin1.jpg);创建按钮llblBegin = new Label(parent, SWT.NO_BACKGROUND);lblBegin.setImage(imageBegin1.getImage();lblBegin.setBounds(70, 40, 75, 38);为按钮各事件写入代码llblBegin.addMouseTrackListener(new MouseTrackAdapter() public void mouseEnter(MouseEvent e) /鼠标移动到按钮上方 lblBegin.setImage(imageBegin2.getImage(); public void mouseExit(MouseEvent e) /鼠标从按钮上方移开 lblBegin.setImage(imageBegin1.getImage(); );lblBegin.addMouseListener(new MouseAdapter() public void mouseDown(MouseEvent e) if (e.button = 1) /按下鼠标左键 lblBegin.setImage(imageBegin3.getImage(); /在这里写入单击事件代码 public void mouseUp(MouseEvent e) if (e.button = 1) /释放鼠标左键 lblBegin.setImage(imageBegin2.getImage(); );4.按钮的功能代码:开始按钮:(BeginButton)setCanvas.setVisible(true);/显示玩家设置界面退出按钮:(ExitButton) System.exit(0);/退出游戏关闭按钮:(CloseButton) System.exit(0);/退出游戏确定按钮:(OKButton) Initialize();/初始化玩家,同时调用JumpChessControl.Initialize();取消按钮:(CancelButton) setCanvas.setVisible(false);/关闭玩家设置界面由于专门有一个类来导入图片(ImageLoader),好处是界面换肤很容易做到,把图片替换就可以了。如何显示棋盘棋子,坐标转换,棋子动画,声音等遇到什么问题(不能退出,尝试解办法失则)四、跳棋算法:1.棋盘坐标定义 坐标定义如图所示,红色数字标识棋盘的区域.2.边界限制如图所示,当X坐标为1时,Y的坐标只能为5,当X坐标为2时,Y的坐标可以5或6。于是我们建立一个数组:final static private int pos = 5,5, /X坐标为1,Y的上限是5,下限是5 5,6, /X坐标为2,Y的上限是5,下限是6 5,7, /X坐标为3,Y的上限是5,下限是7 5,8, /X坐标为4,Y的上限是5,下限是8 1,13, /X坐标为5,Y的上限是1,下限是13 2,13, /6 3,13, /7 4,13, /8 5,13, /9 5,14, /10 5,15, /11 5,16, /12 5,17, /13 10,13, /14 11,13, /15 12,13, /16 13,13, /17;在Position类中IsLegalPosition函数可以确定一个坐标是否合法public static boolean IsLegalPosition(int x, int y) if (x 17) return false;if (y posx - 11) return false;return true;3.棋盘类(ChessBoard)中棋子和坐标的索引关系l棋盘中所有Chess集合private Chess chesses = null;/所有棋子对象都保存这个数组当中下面函数可以根据索引号返回棋子对象public Chess getChess(int index) return chessesindex;l棋子和坐标的对应关系private Position chessesPosition = null;/所有棋子坐标都保存在这个数组当中下面函数可以根据棋子对象或棋子索引号返回坐标public Position getPosition(Chess chess) return chessesPositionchess.getindex();public Position getPosition(int index) return chessesPositionindex;l坐标和棋子的对应关系private Chess chessesIndex = new Chess1717;/数组保存了1717个棋子对象指针下面函数可以根据棋子坐标返回该位置上的棋子,如果没有棋子返回Nullpublic Chess getChess(Position position) if (position = null)return null;return chessesIndexposition.getx() - 1position.gety() - 1;4.下棋规则的算法l坐标的六个方向及相邻坐标的关系在任一个坐标位置上(非边界位置)有相邻六个坐标位置,我们称六个方向分别为:UpLeft、UpRight、Left、Right、DownLeft、DownRight。相邻坐标的关系如下图:下面的代码可以得到相邻坐标:(在Position类实现的)public Position getJoint(Director director) int x = 0;int y = 0;if (director = Director.UpLeft) x = this.x;y = this.y + 1; else if (director = Director.UpRight) x = this.x + 1;y = this.y + 1; else if (director = Director.Left) x = this.x - 1;y = this.y; else if (director = Director.Right) x = this.x + 1;y = this.y; else if (director = Director.DownLeft) x = this.x - 1;y = this.y - 1; else if (director = Director.DownRight) x = this.x;y = this.y - 1;if (IsLegalPosition(x, y) /判断坐标是出边界了return new Position(x, y); else return null;l棋子跳动算法该算法在ChessBoard.CanJumpTo函数中实现找出一个棋子所有可走位置,并建成数据结构“图”的形式l这个算法有点象图的广度优先遍历算法。文字说明如下:1把当前棋子坐标加入“图”中。2从当前棋子位置出发,从六个方向查找棋子可跳的位置,3如果第2步找到坐标没有加入“图”中,就把这些坐标加入“图”中去。4从第3步刚加入“图”中的坐标出发,继续执行第2步。一直到没有坐标加入“图”中为止。l最短路径搜索当用户指定下棋位置以后,还要计算出棋子从当前位置到目标位置的最短路径,为游戏的播放棋子走动动画作准备。这个算法还是有点象图的广度优先遍历算法,文字说明如下:1把所有坐标的“权值”设为12把当前棋子坐标的“权值”设为0。3从当前棋子位置出发,查找棋子可跳的位置。3如果第3步找到坐标没有“权值”为1,就把这些坐标的“权值”在上一坐标的基础上加1。4从第4步刚设定“权值”的坐标出发,继续执行第2步。一直到所有坐标都设定“权值”为止。5从目标位置开始,倒退着开始查找,每次查找的位置应该是“权值”比当前位置减小1的坐标。一直找到起始位置。这样就找到最短路径了。这些的都是数据结构基础知识,有点抽象,只要理解加想象就没有问题了。哦,上次“平安”考试中有一个题目:什么是前序遍厉,什么是后序遍厉,我真的记不住。数据结构的知识能理解能运用,考试却不能得分,冤呀。5.计算机下棋策略这是最难设计的部分,人与计算机的思维方式完全不同,如何把人的下棋思路表示计算机可运算的数据结构,这是比较困难的,要不然人工智能这么多年一直没有突破性进展呢?两坐标间距离计算方法l没有写完五、跳棋控制类所有的工具都做好了,现在要把它组装起来,做好了我们就可以完工了,这个组装没有UML设计,写得有点乱,但是思路是很清晰的,下面画出流程:另外需要说明的是:由于程序是事件驱动的,而且动画显示用记时器实现,在编码上实现上面流程图的思路,还是比较困难的。六、改进计划1.支持网络对战(坐标旋转的问题)2.移植到手机PALM、PPC上3.实现换肤功能,用QQ的图片总是不大好吧。4.提高计算机智能,目前的只能达到QQ中“高级棋师水平”,我在QQ中胜率是70%。七、总结我写跳棋游戏,不是为了玩游戏,只想从中体验编程的快乐。另一方面也看看自己学习能力到底怎样。因为我这是第一次用eclipse做开发,第一次用Java写程序,第一次用UML做设计。花了十来天时间边学边做居然做出来,还比较满意。虽然大大小小项目做过不少,但我从来没有在算法上觉得有难度,跳棋算法是比较复杂的。做完“我的跳棋”在以下几个方面得到锻炼: 学习Java和eclipse,十天时间基本掌握一门全新编程工具应该没有问题。我对一直很欣赏Java,其中有很多先进的编程理念,比如GC,完善的SDK,其中源码写得十分漂亮。Eclipse真是优秀的IDE是我目前觉得最好的一个编程环境。VB,VC,Delphi比起它来是垃圾了。 用了一点UML方面的知识,感觉编程难度不在于某一个函数该怎么写,而在于一个类,一个系统接口如何设计,每个类的功能如何分配,把它们合理的组合关联,从而实现复杂的功能。 另外也决定写一个文档,也该加强这方面的能力。世界上90%的代码都不会被作者以外的人阅读,要与别人交流,表达自己的思路只能借助于文档。中国决不缺少程序员,缺少的文档员。1. packageorg.yushang.jumpchess.app;2. 3. importorg.eclipse.swt.SWT;4. importorg.eclipse.swt.events.MouseAdapter;5. importorg.eclipse.swt.events.MouseEvent;6. importorg.eclipse.swt.events.MouseMoveListener;7. importorg.eclipse.swt.events.MouseTrackAdapter;8. importorg.eclipse.swt.graphics.Color;9. importorg.eclipse.swt.graphics.Point;10. importorg.eclipse.swt.widgets.Composite;11. importorg.eclipse.swt.widgets.Label;12. importorg.eclipse.swt.widgets.Listener;13. importorg.eclipse.swt.widgets.MessageBox;14. importorg.eclipse.swt.widgets.Shell;15. importorg.eclipse.swt.widgets.Display;16. importorg.eclipse.swt.widgets.Text;17. importorg.yushang.jumpchess.Interface.*;18. importorg.yushang.jumpchess.image.ImageLoader;19. importorg.eclipse.swt.widgets.Canvas;20. 21. publicclassAppJumpChess22. 23. privateShellsShell=null;/jve:decl-index=0:visual-constraint=10,10 24. 25. privateJumpChessControljumpChessControl=null;26. 27. privateCanvascanvas=null;28. privateLabellblClose=null;29. privateLabellblTitle=null;30. privateLabellblBegin=null;31. privateLabellblExit=null;32. 33. privateCanvassetCanvas=null;34. privateLabellblOK=null;35. privateLabellblCancel=null;36. 37. privateLabellblType=newLabel6;38. privateTexttxt=newText6;39. 40. privatebooleanmouseDown=false;41. privatePointlastMousePoint=null;42. 43. /*44. *Thismethodinitializescanvas45. *46. */47. privatevoidcreateCanvas()48. canvas=newCanvas(sShell,SWT.NO_BACKGROUND);49. canvas.setBounds(neworg.eclipse.swt.graphics.Rectangle(0,0,800,600);50. 51. 52. privatevoidcreateClose(Compositeparent)53. finalImageLoaderimageClose1=newImageLoader(sShell.getDisplay(),Close1.jpg);54. finalImageLoaderimageClose2=newImageLoader(sShell.getDisplay(),Close2.jpg);55. finalImageLoaderimageClose3=newImageLoader(sShell.getDisplay(),Close3.jpg);56. 57. lblClose=newLabel(parent,SWT.NO_BACKGROUND);58. 59. lblClose.addMouseListener(newMouseAdapter()60. publicvoidmouseDown(MouseEvente)61. if(e.button=1)62. lblClose.setImage(imageClose3.getImage();63. 64. 65. 66. publicvoidmouseUp(MouseEvente)67. if(e.button=1)68. lblClose.setImage(imageClose2.getImage();69. sShell.dispose();70. 71. 72. );73. 74. lblClose.addMouseTrackListener(newMouseTrackAdapter()75. publicvoidmouseEnter(MouseEvente)76. lblClose.setImage(imageClose2.getImage();77. 78. publicvoidmouseExit(MouseEvente)79. lblClose.setImage(imageClose1.getImage();80. 81. );82. 83. lblClose.setImage(imageClose1.getImage();84. lblClose.setBounds(765,4,26,20);85. 86. 87. privatevoidcreateTitle(Compositeparent)88. finalImageLoaderimageTitle=newImageLoader(sShell.getDisplay(),Title.jpg);89. lblTitle=newLabel(parent,SWT.NO_BACKGROUND);90. lblTitle.addMouseMoveListener(newMouseMoveListener()91. publicvoidmouseMove(MouseEvente)92. if(mouseDown)93. PointnowMousePoint=newPoint(e.x,e.y);94. if(lastMousePoint.equals(nowMousePoint)95. return;96. 97. 98. Pointpoint=sShell.getLocation();99. point.x+=(nowMousePoint.x-lastMousePoint.x);100. point.y+=(nowMousePoint.y-lastMousePoint.y);101. sShell.setLocation(point);102. 103. 104. );105. 106. lblTitle.addMouseListener(newMouseAdapter()107. publicvoidmouseDown(MouseEvente)108. mouseDown=true;109. lastMousePoint=newPoint(e.x,e.y);110. 111. publicvoidmouseUp(MouseEvente)112. mouseDown=false;113. 114. );115. lblTitle.setImage(imageTitle.getImage();116. lblTitle.setBounds(0,0,800,28);117. 118. 119. privatevoidcreateBeginButton(Compositeparent)120. finalImageLoaderimageBegin1=newImageLoader(sShell.getDisplay(),Begin1.jpg);121. finalImageLoaderimageBegin2=newImageLoader(sShell.getDisplay(),Begin2.jpg);122. finalImageLoaderimageBegin3=newImageLoader(sShell.getDisplay(),Begin3.jpg);123. lblBegin=newLabel(parent,SWT.NO_BACKGROUND);124. 125. lblBegin.addMouseListener(newMouseAdapter()126. publicvoidmouseDown(MouseEvente)127. if(e.button=1)128. lblBegin.setImage(imageBegin3.getImage();129. 130. 131. publicvoidmouseUp(MouseEvente)132. if(e.button=1)133. lblBegin.setImage(imageBegin2.getImage();134. setCanvas.setVisible(true);135. 136. 137. 138. );139. 140. lblBegin.addMouseTrackListener(newMouseTrackAdapter()141. publicvoidmouseEnter(MouseEvente)142. lblBegin.setImage(imageBegin2.getImage();143. 144. publicvoidmouseExit(MouseEvente)145. lblBegin.setImage(imageBegin1.getImage();146. 147. );148. 149. lblBegin.setImage(imageBegin1.getImage();150. lblBegin.setBounds(620,540,75,38);151. 152. 153. privatevoidcreateExitButton(Compositeparent)154. finalImageLoaderimageExit1=newImageLoader(sShell.getDisplay(),Exit1.jpg);155. finalImageLoaderimageExit2=newImageLoader(sShell.getDisplay(),Exit2.jpg);156. finalImageLoaderimageExit3=newImageLoader(sShell.getDisplay(),Exit3.jpg);157. lblExit=newLabel(parent,SWT.NO_BACKGROUND);158. 159. lblExit.addMouseListener(newMouseAdapter()160.
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生活污水治理项目可行性分析报告
- 网课课件重点
- 一 阿Q正传(节选)教学设计-2025-2026学年中职基础课-拓展模块 下册-高教版(2023)-(语文)-50
- 灾后心理干预策略-第1篇-洞察及研究
- 网络基本知识培训课件下载
- 消防安全题材校园短剧(3篇)
- 1.2.2植物细胞说课稿-2023-2024学年人教版生物七年级上册
- 三年级数学计算题专项练习及答案
- 7.13 阿细跳月 教学设计-2023-2024学年高中音乐人音版(2019)必修 音乐鉴赏
- 规划与建筑方案设计英文(3篇)
- CPK数据图表生成器
- 汽车整车制造设备采购协议书
- 割草机 打草机 割灌机正确使用方法
- 医保异地备案个人承诺书
- 新教师入职培训-如何上好高中化学课
- 小学道法一 最广泛、最真实、最管用的民主课件
- 2023年广东省深圳市新七年级小升初英语分班考试(含答案)
- 重庆.住宅物业单位服务等级标准
- 贵阳市物业服务合同示范文本
- 循证医学中常用的统计指标演示
- 生物化学英文版教学课件:Biochemistry-chapter 1(英文1)
评论
0/150
提交评论