五子棋游戏总体设计和实现.docx
《五子棋游戏总体设计和实现.docx》由会员分享,可在线阅读,更多相关《五子棋游戏总体设计和实现.docx(20页珍藏版)》请在冰点文库上搜索。
五子棋游戏总体设计和实现
4.系统总体设计和实现
4.1总体设计分析
总体设计是软件开发过程中另一个关键阶段,在这一阶段中将依据需求分析中提出逻辑模型,科学合理地进行物理模型设计。
这个阶段关键目标是将反应用户信息需求逻辑方案转换成物理方案,并为下一阶段提供必需技术资料。
4.1.1总体设计标准
(1)整体性:
软件是作为统一整体而存在。
所以,在总体设计中要从整个软件角度进行考虑。
(2)灵活性:
为保持软件长久生命力,要求该手机游戏软件含有很强环境适应性。
为此,游戏软件应含有很好开放性和结构可变性。
(3)可靠性:
可靠性是指软件抵御外界干扰能力及受外界干扰时恢复能力。
(4)经济性:
经济性是指在满足游戏软件需求前提下,尽可能地减小游戏软件开销。
4.1.2软件模块总体设计
软件中各模块之间关系通常利用层次图来表示。
它是一个一系列多层次用树形结构矩形框描绘数据层次结构框图。
一个单独矩形框作为树形结构顶层,各个数据子集由下面各层矩形框代表,最底层各个矩形框代表组成这个数据实际数据元素(不能再分割元素),它代表完整数据结构。
这模式很适合于需求分析阶段需要,层次方框图对数据结构描绘伴随结构精细化也越来越具体。
反复细化沿着图中每条路径,从对顶层信息分类开始,直到确定了数据结构全部细节为止。
图4-1游戏功效结构
本研究中将游戏软件分为三大模块,图4-1所表示,包含:
游戏选项、游戏设置和帮助。
根据在调研中搜集资料对每个模块功效进行编排制作。
依据上述功效分析,本研究中,将游戏软件在三大模块基础上又对每一大模块又分为多个子模块:
游戏选项包含六个模块:
开始游戏、重新游戏、悔棋、认输、背景音乐和退出游戏。
游戏设置包含三个模块:
前后手设置、棋盘底纹颜色设置和棋盘大小设置。
帮助包含两个模块:
游戏帮助和相关。
4.2游戏设计
4.2.1游戏前准备
本游戏在开发之前需要做部分前期准备工作,尤其是对于精通五子棋游戏Java游戏开发者来说。
通常情况下,一款利用起来比较熟练地J2ME开发工具是必不可少。
本游戏使用是J2ME简化开发工具SunJava(TM)WirelessToolkit2.5.2forCLDC,她需先将Java虚拟机安装调试好以后才能使用。
WTK2.5.2不带有文本编辑功效,所以需要另寻搭配使用。
本游戏采取UltraEdit进行编辑。
本游戏需要几张后缀名为.png格式卡通图,除了一张用作五子棋游戏Logo外,其它全部将在游戏中使用。
4.2.2游戏界面和事件驱动设计
游戏界面设计采取传统游戏界面风格,图4-2所表示。
游戏设计中采取传统界面游戏风格,首先开启游戏,然后进入游戏开始界面,界面中放置“设置”、“开局”、“帮助”、“相关”四个选项供玩家选择。
其中“设置”选项关键是对游戏相关功效进行设置,如游戏难度设置。
另外还有“悔棋”、“重玩”等项目标设置。
除此之外还包含查看游戏帮助、游戏介绍等。
图4-2游戏界面设计
所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑实施什么操作(即调用什么函数)。
当然事件不仅限于用户操作。
我们知道,事件是事件驱动关键自然是。
从事件角度说,一个事件搜集器、一个事件发送器和一个事件处理器组成了事件驱动程序基础结构。
事件搜集器专门负责搜集包含来自硬件(如时钟事件等)、来自用户(如键盘、鼠标事件等)及来自软件(如应用程序本身、操作系统等)全部事件。
将搜集器搜集到事件分发到目标对象中则由事件发送器负责完成。
具体事件响应工作则由事件处理器完成,它需要利用虚函数机制(函数名取为类似于HandleMsg一个名字),它往往要到实现阶段才完全确定。
事件处理器对于框架使用者来说是她们唯一能够看到。
棋类游戏通常含有两个关键特征,首先是对战双方轮番落子,其次是落子间隔通常是不确定,尤其是对战后期,可能每一步棋全部要经过深思熟虑,不管是人还是计算机,全部无法对时间间隔有事先预期。
基于以上两个特征,本游戏摒弃了大多数游戏采取线程或定时器驱动游戏方法,而采取了事件驱动方法,即玩家键盘或触摸笔触发游戏下一个动作。
事件驱动大大降低了无须要工作量,只有玩家发出消息时,计算机才开启运算,而在玩家思索期间,计算机不做任何运算和重绘操作。
4.2.3游戏类设计
五子棋游戏属于二维棋类游戏,所以能够定义一个Chesses类来表示棋子,用一个Chess类型二维数组来包含棋盘上全部棋子,对于该棋子玩家区分使用Chessesboolean型变量isPlayer1来区分。
能够考虑直接生成数组每一个对象而不是在数组建立后,而是把每一个棋子对象(Chesses)放在游戏进行中生成,这关键是考虑到移动设备资源有限,尽可能降低系统资源占用。
这么在游戏进行时,能够避免还没有下棋子在一开始就占用了系统内存,玩家每下一步棋,在数组对应位置生成该棋子对象。
对于游戏中每一类设计,首先就是一个MIDlet类,Gobang类继承自MIDlet类,经过方法startApp,pauseApp,destroyApp来通知游戏开始,暂停和销毁结束,用于连接设备应用程序管理器(ApplicationManager)。
本游戏共由7个类组成,它们各自功效以下:
(1)GobangMIDlet类
负责程序开启和屏幕之间切换;
(2)GobangCanvas类
玩家对战平台,她继承于Canvas类;
(3)Setting类
用于创建游戏各项设置参数表单;
(4)GobangLogic类
游戏逻辑类,负责胜败判定和计算机落子;
(5)Dot类
棋子类,包含了棋子位置信息;
(6)Help类
游戏帮助类,包含五子棋部分常识信息和五子棋教学内容;
(7)About类
游戏相关类,包含游戏版本、版权等信息。
各个类之间关系图4-3所表示:
图4-3游戏类设计
4.2.4游戏步骤设计
对于棋盘界面更新,游戏进行绘制棋子时是根据棋子二维数组来完成,玩家下棋后,设置isPlayer1值,程序修改数组对应位置,然后重新绘制(repaint)。
为了使游戏操作尽可能简便,本文设计上不在游戏进入时设计菜单,玩家能够直接开始对战,而是在开始游戏过程中设置重新开始和退出按钮。
即一键开始,运行即玩,重来或退出全部使用一键操作。
游戏步骤设计依据关键是游戏界面设计和游戏类设计。
游戏开启时,GobangMIDlet对象先显示游戏主屏幕,在屏幕下方一侧是出软键(软键指描述抽象用户端设备怎样显示),另一侧是用软件组成菜单,菜单元素关键有“开局”、“游戏设置”、“游戏帮助”、“相关”选项。
当玩家选择“游戏设置”软键时,则显示游戏参数设置表单;当玩家选择“开局”软键时,则显示游戏对战主界面;当玩家选择“游戏帮助”软键时,则显示游戏帮助表单;当玩家选择“相关”软键时,则显示游戏相关表单。
玩家进入游戏参数设置表单,当玩家按下“确定”软键时,则确定目前游戏参数,返回游戏主屏幕;当玩家按下“取消”软键时,则放弃此次对游戏修改,直接返回游戏主屏幕。
玩家进入游戏对战画布,对战中画布有两个软键,当玩家按下“返回主菜单”软键时,则退出游戏抵达游戏主菜单;当玩家按下“悔棋”软键时,则进行悔棋操作;当游戏结束时,“悔棋”软键被换成了“重玩”软键。
玩家进入游戏介绍表单,当玩家按下“确定”软键时,返回游戏主屏幕。
4.2.5游戏算法设计
1、五子棋获胜组合
有哪些获胜组合是在一场五子棋游戏中计算机必需要知道,所以,获胜组合总数必需要求得。
在本文中我们假定目前棋盘为15*15:
(1)每一列获胜组合是11,共15列,计算水平方向获胜组合数,所以水平方向获胜组合数为:
11*15=165。
(2)每一行获胜组合是11,共15列,则可计算垂直方向获胜组合总数,垂直方向获胜组合数为:
11*15=165。
(3)同理,可计算正对角线方向获胜组合总数,正对角线上获胜组合总数为11+(10+9+8+7+6+5+4+3+2+1)*2=121。
(4)计算反对角线上获胜组合总数。
计算反对角线方向获胜组合总数可计算为11+(10+9+8+7+6+5+4+3+2+1)*2=121。
这么可计算得全部获胜组合数为:
165+165+121+121=572。
2、设计获胜棋型
经过上面计算,一个15*15屋子棋盘在此已经计算出了会有572中获胜方法,所以,我们就能够利用数组建立部分常规棋型,棋型关键作用是:
(1)判定是否有任何一方获胜;
(2)依据目前格局判定最可能落子方法。
然而在现实中,高手留给我们经验就是把握前奏,如“冲四”、“活三”,除了“连五”以外,这些也是同向胜利捷径。
3、攻击和防守
获胜棋型算法是中性,不区分计算机和玩家,这就包含到攻击和防守何者优先问题。
而很多高手全部认为五子棋根本是“防守”,“攻击”是灵魂。
进攻是取胜手段,是防守延续和发展。
很多经验和研究表明,一个棋手只要掌握了全方面、基础防守原理和技巧,就能和比自己棋力高一个等级进攻型选手对抗,起码能立于不败之地。
对手进过越偏激,则防守效果越好。
没有进攻防守就像只开花不结果,没有实际意义,顽强防守是反攻前奏,没有进攻延续,防守也失去了价值。
而这缺一不可。
依据以上原理,计算机在接收最好攻击位置之前,还要计算目前玩家最好攻击位置。
假如玩家存在最好攻击位置,那么计算机就将下一步棋子摆在玩家最好攻击位置上以阻止玩家进攻,不然计算机便将棋子下在自己最好攻击位置上进行攻击。
4、用到经典算法
(1)坐标变换算法
游戏实质其实是对所下棋子位置进行操作和判定,所以将己方、对方和棋盘上空点位置坐标存放在对应List中。
我对所下棋子坐标进行了处理,因为我所采取棋盘为15*15,所以棋子横坐标为0到14整数,纵坐标也为0到14整数。
所以,每次在棋盘上下子以后,计算机在存放该点坐标时,便要对坐标进行加工。
假设左上角点为firstPoint,它实际坐标为(x1,y1),而我是将它作为(0,0)存放,其它坐标,其它点全部是以该点为标准进行变换,假设棋盘上每个格子宽度为w,某实际点为(x2,y2),变换后坐标为(x,y),x=(x2-x1)/w,y=(y2-y1)/w。
(2)胜败判定算法
胜败判定规则很简单,就是判定游戏双方棋子在同一条水平线、同一条竖线或是同一条斜线上谁先出现5个连续棋子,谁先达成这么目标,谁就取得胜利。
在本设计中,是在每次下完一个子后进行判定,看己方是否达成了胜利标准,若胜利游戏便结束;不然,游戏继续。
(3)人工智能算法
人工智能算法主体思想分为以下三个步骤:
第一步:
依据双方目前形势循环地假设性分别给自己和对方下一子(在某个范围内下子),并判定此棋子能带来形势上改变,如能不能冲4,能不能形成我方或敌方双3等。
第二步:
依据上一步结果,组合每一步棋子所带来全部结果(如某一步棋子可能形成我方1个活3,1个冲4(我叫它半活4)等),包含敌方和我方。
第三步:
依据用户给规则对上一步结果进行排序,并选子(有进攻形、防守形规则)。
5、经典类具体设计
(1)应用程序类
Gobang类用于连接设备应用程序管理器(ApplicationManager),Gobang类继承自MIDlet类,经过Gobang类方法startApp,pauseApp,destroyApp来通知游戏开始,暂停和销毁结束。
源代码以下:
packagecom.occo.j2me.game.gobang;
importjavax.microedition.lcdui.Display;
importjavax.microedition.midlet.MIDlet;publicclassGobangextendsMIDlet
//定义游戏界面Canvas类GobangCanvas对象Gobangpublic
{GobangCanvasgobang;
Gobang(){
super();
gobang=newGobangCanvas(this);//生成GobangCanvas类对象gobang
}protectedvoidstartApp(){
Display.getDisplay(this).setCurrent(gobang);
}protectedvoidpauseApp(){
}protectedvoiddestroyApp(booleanarg0){
}}//在屏幕上绘出游戏见面gobang
(2)游戏界面类
GobangCanvas类继承自Canvas,游戏关键类是GobangCanvas类,这类将完成游戏绘图、互动、控制、逻辑、等全部功效,这类框架代码以下:
Packagecom.occo.j2me.game.gobang;
importjavax.microedition.lcdui.Displayable;
importjavax.microedition.lcdui.Command;
importjavax.microedition.lcdui.Canvas;
importjavax.microedition.lcdui.CommandListener;
publicGobangCanvas(Gobanggobang){
this.gobang=gobang;}
protectedvoidpaint(Graphicsg){
}
importjavax.microedition.lcdui.Graphics;publicclassGobangCanvasextendsCanvasimplementsCommandListener{protectedGobanggobang;publicGobangCanvas(){}
}
(3)棋子类
整个棋盘是一个Chesses类型二维数组,棋盘上每一个棋子全部对应着一个Chesses对象,这类定义了一个棋子,源代码以下:
packagecom.occo.j2me.game.gobang;
publicChesses(){}
publicclassChesses{booleanisPlayer1;
publicChesses(booleanisPlayer1){
this.isPlayer1=isPlayer1;
}}
4.3游戏实现
4.3.1主类实现
YpkWuZiQiActivity类是五子棋游戏主类,同时也是五子棋游戏入口,它继承自Activity类。
进入程序后,首先调用init()方法,init()方法经过调用setContentView(R.layout.welcomeview)显示登录该游戏第一个界面。
welcomeview.xml是一个布局文件,里面存放了界面信息。
该界面中有四个Button,分别为welButton1、welButton12、welButton3、welButton4,点击每个Button全部会触发一个事件,其中点击welButton1和welButton2还会给它组员变量FIGHTINGMODE赋值,因为在人人对战和人机对战是写在同一个ChessBoard类中,所以需要经过FIGHTINGMODE值来区分是人人对战还是人机对战。
点击welButton1时,FIGHTINGMODE=1,然后会调用initTwo()方法,该方法经过调用setContentView(R.layout.chess)方法,来显示对战界面。
chess.xml文件存放了对战界面信息。
在chess.xml文件中调用了ChessBoard类,该类中关键定义了棋盘信息,下文会对该类做具体介绍。
在对战界面中也有四个Button,分别是b1、b2、b3、b4。
首先来介绍一下b2,该Button功效是返回主页,调用init()方法就能够实现。
b3功效是重新开始,这个也只需要调用initTwo()方法。
b3功效是退出,调用了系统方法:
System.exit
(1)。
下面关键介绍一下b1,该Button功效是悔棋。
该Button设定点击事件具体内容以下:
b1.setOnClickListener(newOnClickListener(){
publicvoidonClick(Viewv){
ChessBoardchess=(ChessBoard)findViewById(R.id.chess);
Pointtemp=null;
if(chess.whoRun==1){
if(chess.firstPlayer.getMyPoints().size()>=1&&chess.secondPlayer!
=null){
temp=chess.secondPlayer.getMyPoints().get(chess.secondPlayer.getMyPoints().size()-1);
chess.secondPlayer.getMyPoints().remove(temp);
chess.freePoints.add(temp);
temp=chess.firstPlayer.getMyPoints().get(chess.firstPlayer.getMyPoints().size()-1);
chess.firstPlayer.getMyPoints().remove(temp);
chess.freePoints.add(temp);
chess.freshCanvas();
}
}
if(chess.whoRun==2){
if(chess.firstPlayer.getMyPoints().size()>=1&&chess.secondPlayer!
=null){
temp=chess.firstPlayer.getMyPoints().get(chess.firstPlayer.getMyPoints().size()-1);
chess.firstPlayer.getMyPoints().remove(temp);
chess.freePoints.add(temp);
temp=chess.secondPlayer.getMyPoints().get(chess.secondPlayer.getMyPoints().size()-1);
chess.secondPlayer.getMyPoints().remove(temp);
chess.freePoints.add(temp);
chess.freshCanvas();
}
}
}
})
首先获取ChessBoard对象,该对象继承自View,具体定义了棋盘信息,关键负责显示棋盘内容。
接下来判定一下触发悔棋事件是哪一个玩家,再判定是否符合悔棋条件,这个条件很简单,就是棋盘上最少要有两个棋子。
以后便进行悔棋操作,分别将两个玩家最终下棋子取出,程序实现就是将两个ArrayList最终一个元素remove出来,再分别放到统计棋盘中没有棋子点集合中,最终更新一下画布,关键是调用ChessBoardinvalidate()方法。
经过以上步骤以后,展现在我们面前便是悔完棋画面了。
点击welButton2时,FIGHTINGMODE=2,以后步骤便会点击welButton1是相同了,不一样是,因为对战模式改变,从人人对战变成了人机对战。
点击welButton3时,经过initThree()方法调用setContentView(Rchess)方法实现网络对战。
具体对战实现细节将会在下文一一介绍。
在这个界面中只保留了两个Button:
b2和b4。
这两个Button所实现功效和上面b2和b4是相同。
最终,welButton4比较简单。
它所实现功效为退出应用程序,调用System.exit
(1)方法。
4.3.2游戏设置类实现
游戏设置表单用来对游戏参数进行设置,包含棋盘大小、先手选择、智能等级。
表单中使用了Gauge和ChoiceGroup两种高级用户界面组件。
1、棋盘尺寸选择
标准五子棋棋盘为15*15,但为了满足不一样玩家需求,这里提供了大小为10*10到20*20棋盘,用户能够经过Gauge组件改变。
棋盘最小值为10,而Gauge组件最小值为0,所以目前Gauge值需要角上10才是目前棋盘大小。
创建Gauge组件代码以下:
form=newForm("游戏设置");//创建参数设置表单并添加标签
gaugeSize=newGauge("棋盘规格:
"+boardSize+"X"+boardSize,true,10,boardSize-10);//棋盘规格
form.append(gaugeSize);
图4-4棋盘尺寸设计
在Gauge交互模式下能够为Gauge对象所在表单对象绑定一个ItemStateListener事件监听器,并在监听器上捕捉Gauge对象事件,当Gauge值发生改变时就会触发事件。
这里将依据Gauge目前值改变标签,显示目前棋盘大小。
其代码以下:
publicvoiditemStateChanged(Itemitem)
{
if(item==gaugeSize)//当Gauge组件发生改变时
{
intbs=gaugeSize.getValue()+10;//获取目前Gauge值并计算棋盘大小(加10)
gaugeSize.setLabel("棋盘规格:
"+bs+"X"+bs);//改变Gauge组件标签
}
}
2、难度选择
游戏难易程度依据计算机智能等级来控制,创建及添加选项方法和复选框一样,所不一样是在创建ChoiceGroup对象时,类型设置为1(单选)。
对于单选框,setSelectedIndex只能用来指定某个选项被选中,所以,布尔值selected值肯定为true,不然便没有意义。
游戏共有3个难度等级,分别是:
拜师学艺、棋行天下、谁和争锋(此游戏中并未作出区分),初始情况下为拜师学艺,该选项索引值为0。
创建难度选择单选框代码以下:
level=1;//默认情况下难度等级
choicelevel=newChoiceGroup("电脑智能等级:
",1);//创建难度等级选项组
choicelevel.append("拜师学艺",null);//难度1
choicelevel.append("棋行天下",null);//难度2
choicelevel.append("谁和争锋",null);//难度3
choicelevel.setSelectedIndex(level-1,true);//设置默认情况为难度1,索引值为0
form.append(choicelevel);//将选项组添加到主表单中
游戏设置选项表单还有两个Command对象,分别用于玩家却热和取消,所以表单需要监听软键事件和组件事件:
publicclassSettingimplements