网络象棋游戏的开发及测试.docx
《网络象棋游戏的开发及测试.docx》由会员分享,可在线阅读,更多相关《网络象棋游戏的开发及测试.docx(25页珍藏版)》请在冰豆网上搜索。
网络象棋游戏的开发及测试
心之所向,所向披靡
武汉理工大学华夏学院
课程设计报告书
课程名称:
软件测试综合设计
题目:
网络象棋游戏的开发及测试
系名:
信息工程系
专业班级:
软件1091
姓名:
学号:
指导教师:
司晓梅、钱小红
2013年1月4日
课程设计任务书
学生姓名:
专业班级:
软件1091
指导教师:
司晓梅工作单位:
信息工程系
设计题目:
网络象棋游戏的开发及测试
初始条件:
jdk1.5+eclipse(netbeans)
要求完成的主要任务:
用Java语言实现一个网络象棋游戏软件,并对实现后的软件进行测试。
要求按照IEEE标准模板给出具体的测试计划书、软件的黑盒测试用例规格说明,并按照测试用例进行测试,提交缺陷报告。
提示:
IEEE标准测试文档模板可以参阅人民邮电出版社佟伟光主编的教材《软件测试》
设计报告撰写格式要求:
1设计题目与要求
2设计思想
3系统结构
4数据结构的说明和模块的算法流程图
5使用说明书(即用户手册)、运行结果、关键界面截图
6测试计划说明书、测试用例规格说明、缺陷报告
7自我评价与总结
8附录:
程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释;
时间安排
12月24日~12月29日完成网络象棋游戏的开发、系统的打包和验收;
1月2日~1月4日完成测试计划、测试用例的设计、测试缺陷报告的写作,并将以上工作整理成为课程设计报告,于1月4日下午提交课程设计报告。
指导教师签字:
2012年12月15日
系主任签字:
2012年12月16日
1设计题目与要求
1.1设计题目
网络象棋游戏的开发及测试
1.2设计要求
用Java语言实现一个网络象棋游戏软件,并对实现后的软件进行测试。
使用的开发环境是:
JDK1.5及MyEclipse。
黑方先走或红方先走都可。
要求给每个棋子定义标准的走法规则。
红黑方对弈。
写出各个棋子走法的测试用例。
2设计思想
首先在画布上确定位置画出棋盘。
象棋是双方在有着9条竖线和10条横线的棋盘上对弈,对弈的竖线与横线的交叉点称做棋点,每个棋子都是在棋点上行走而不是在方格中行走河界将棋盘分成两个等份。
每一边都有一块由9个点组成的九宫棋子。
将、帅、士只能在九宫内移动,并且将帅每一步只可以水平或垂直移动一个棋点。
士(仕),它只能在九宫内移动,并且它每一步只可以沿对角线方向移动一个棋点;象(相),它必须一步沿对角线方向走两个棋点,但它既不能过河,也不能跳过或穿越障碍,即象在走的过程中不能被别眼;马(馬),每一步只可以水平或垂直移动一个棋点,但必须按对角线方向,向左或右移动,象棋的马不能跳过障碍,即在走的过程中不能被别腿;车(車),可以水平或垂直方向移动任意个无阻碍的点;炮,移动起来和车很类似,但它必须跳过一个棋子来吃掉对方的一个棋子,被跳过的那个棋子称为桥或者屏风;兵(卒),每步只能向前移动一个棋点,过河以后,它便增加了向左右移动的能力,兵不允许向后移动。
画出10条横线和9条竖线形成90个正方形(边长为50)的小方格,4条对角线构成帅和将的九方格。
一个和棋盘背景颜色相同的填充矩形形成红黑方的分界。
然后画出棋子。
首先定义棋子,用一个二维数组来初始化这些棋子。
即用二维数组的值来表示棋子,如果为0,表示没有棋子;1-7表示黑方的("車","馬","象","仕","将","炮","卒");8-14表示红方的("车","马","相","士","帅","炮","兵")。
然后画棋子,两层for循环遍历棋盘中每个交叉的点,在每个点上画出适当的圆,根据初始化二维数组的对应的行和列的值来显示相应的棋子。
即根据条件判断,等于0的没有棋子,在1-7之见的分别显示黑方的("車","馬","象","仕","将","炮","卒"),在8-14之间的分别显示红方的("车","马","相","士","帅","炮","兵")。
移动棋子。
其实就是监听了鼠标点击相应事件,先选棋子,通过点击了某一个有效的棋子区域,就将该点转化为棋子所在的行和列,再点击其他的有效区域,将先前的棋子的值复值给新的区域的值,并将原来的区域的值改为0,最后再调用repaint(),就实现了棋子的移动效果了。
3系统结构
系统结构流程图
temp=0temp=1
NoNo
YesYes
图3-1系统结构流程图
4数据结构的说明和模块的算法流程图
4.1象棋游戏主要模块
4.1.1主窗口模块Chess.java该java文件的类负责创建中国象棋的"主窗口",该文件含有main方法,程序从该类开始执行。
4.1.2棋盘模块ChessBoard.java该文件生成的类负责创建"对弈棋盘"对象,用户可以用鼠标拖动棋盘上棋子进行对弈,当松开鼠标时将棋子固定到棋点,该棋盘使得用户不能将棋子拖放到非棋点上,棋盘的Rule对象负责判断走棋是否遵守了象棋的规则,例如:
"马"走日,"象"走田,小卒一去不回头等等,如果用户的走法不符合规则,棋子将不动,重新选择路线在落子。
4.1.3棋点模块ChessPoint.java该文件生成的类负责创建棋盘的棋点对象,棋点对象可以判断该棋点上是否有棋子,可以指定当前棋点上的棋子,获取当前棋点上的棋子,移掉当前棋点上的棋子。
4.1.4绘制棋子模块ChessPiece.java该文件生成的类负责创建棋子对象,并绘制棋子的外观,棋子对象可以获取本身的颜色、大小、名字,也可以设置和获取本身的类别-红棋或黑棋。
4.1.5规则模块Rule.java该文件生成的类负责为创建走棋法则对象,该对象负责判断用户的走着是否遵守了中国象棋规则。
4.1.6记录走棋模块MakeStep.java该类创建的对象负责记录一步走棋。
5使用说明
5.1点击运行,显示棋盘界面,红黑双方自动摆好棋子准备对战
图5-1棋盘界面图
该棋盘是由10条横线和9条竖线形成90个正方形(边长为50)的小方格,并在帅和将所在的特殊位置画出相应的对角线来,中间是由一个和棋盘背景颜色相同的填充矩形形成红黑方的分界,炮和兵(卒)初始化所对应的位置的棋盘背景是由相应的直线所画出来的。
用一个二维数组来定义相应的棋子,用二维数组的下标来表示该棋子所在的行和列,用二维数组的值来表示相应的棋子,即0表示没有棋子,1-7表示黑方的("車","馬","象","仕","将","炮","卒"),8-14表示红方的("车","马","相","士","帅","炮","兵")。
5.2选择棋子,开始走棋
图5-2选棋落子
用变量temp当做一个开关来切换红黑两方走棋的顺序。
初始值为0表示红方先走,红方走完后立即将该temp值改为1,当再次点击棋子时,只能使用黑方了,黑方同理。
当选中一方的棋子时,将选中的当前行赋值给selectRow,将选中的当前列赋值给selectCol,然后调用repaint()方法,并在paint()方法中进行判断,如果selectRow和selectCol的值发生了变化,就在变化的位置处画上相应的正方形。
走棋的原理是:
先选中棋子,将先前的棋子的值赋值给新的区域的值,并将原来的区域的值改为0,最后再调用repaint(),就实现了棋子的移动效果了。
实现了棋子的移动效果后就要去实现各类棋子的走法规则,即让每个棋子按照规定的法则来移动。
如若棋子不是按规定走的将不会有所改变,需在重新选择有效路径。
6测试用例规格说明
6.1中国象棋中走马的测试用例
6.1.1分析中国象棋中走马的实际情况
1.如果落点在棋盘外,则不移动棋子;
2.如果落点与起点不构成日字型,则不移动棋子;
3.如果在落点方向的邻近交叉点有棋子(绊马腿),则不移动棋子;
4.落点处有己方棋子,则不移动棋子;
5.如果不属于1-4条,落点处无棋子,则移动棋子;
6.如果不属于1-4条,落点处为对方棋子(非老将),则移动棋子并除去对方棋子;
7.如果不属于1-4条,且落点处为对方老将,则移动棋子,并提示战胜对方,游戏结束。
6.1.2根据分析明确原因和结果
原因:
1.落点在棋盘上;
2.落点与起点构成日字;
3.落点方向的邻近交叉点无棋子;
4.落点处为自己方棋子;
5.落点处无棋子;
6.落点处为对方棋子(非老将);
7.落点处为对方老将。
结果:
E1、不移动棋子;
E2、移动棋子;
E3、移动棋子,并除去对方棋子;
E4、移动棋子,并提示战胜对方,结束游戏。
6.1.3添加中间节点11,目的是作为导出结果的进一步原因,简化因果图导出的判定表
图6-1判定表
6.1.4决策表分解
图6-2决策表分解
6.2兵(卒)的走法规则及测试结果图
走法规则:
兵(卒)没有过河时只能竖着向前面走且有且只能移动一步,当过河后可以竖着向前面走,也可以横着左右走,但是不能往后走。
如下图:
图6-3没有过河可移动位置图6-4过河后可移动的位置
6.3炮的走法规则及测试结果图
走法规则:
炮隔三打子。
当炮在横纵轴方向上没有遇到障碍物时可以随意移动,一旦有障碍物出现的话,障碍物的前方必须存在有对方棋子时,才能移动到对方的棋子位置处如下图:
图6-5炮走动图
6.4车(車)的走法规则及测试结果图
走法规则:
车横冲直撞。
车只能在横纵轴方向上随意移动,且不能越过障碍物,如果有障碍物的话,也只能是对方的棋子所造成的障碍,此时可以移动到对方棋子所在的位置。
图6-6车走动图
6.4马(馬)的走法规则及测试结果图
走法规则:
马跳日。
当马在横向(或纵向)的方向上跳动时,如果在横向(纵向)的方向上没有障碍物的话,马才能跳过去,否则就跳不过去。
图6-7马走动图
6.5象(相)的走法规则及测试结果图
走法规则:
象(相)飞田。
当象(相)往前方(或后方)跳动时,如果在田子的中心位置没有障碍物出现,象(相)才能走动,否则它将不能移动。
并且象(相)是不能过河的。
如图:
图6-8相走动图
6.6仕(士)的走法规则及测试模拟图
走法规则:
仕(士)只能在九方格的对角线上行走,且每次只能移动一格。
如图:
图6-9仕走动图
6.7帅(将)的走法规则及测试结果图
走法规则:
帅(将)只能在九方格中的横纵轴上行走,且每次只能移动一步。
如图:
图6-10帅走动图
7.自我评价与总结
通过此次课程设计,使得我对测试进一步熟悉,对JAVA编程也进一步加强。
对于这次使用Java语言编写出象棋游戏的设计,很重要一点就是我们要知道象棋有哪些规则,象棋的摆发,棋子走动的规律,再用程序化的语言通过算法来设计出象棋游戏。
象棋的规则开始并不熟悉,通过网上查询,了解了象棋走法。
首先要将棋盘制作出来,在相应的位置摆上棋子,通过调用Java的API将它们画出来的。
一开始什么都不会,通过老师的讲解,思路慢慢明朗化。
象棋游戏开发完成,必须先测试,通过黑盒测试,探测此次开发象棋游戏功能是否正确,界面是否达到标准。
要是不满足,还得继续修改程序,进步完善。
开发过程中并没有出现太大的问题,有什么不清楚的,通过向老师同学请教,都顺利解决了。
通过此次课程设计,不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
理论与实际相结合才能是自己学得更多,学的更扎实。
通过理论实践相结合可以提高自己的实际动手能力和独立思考的能力。
通过这次,让我了解到自己还有许多不足,知识学的并不牢靠,实践能力有待加强,各方面能力还需不断提高。
附录:
程序清单
packagecom.game;
importjavax.swing.JFrame;
/**
*此类是窗体类的子类,就是一个窗体
*/
publicclassGuiextendsJFrame{
//定义一张白纸
privateMyCanvasec;
//在本窗体类的构造函数,来设计这个窗体
publicGui()
{c=newMyCanvase();//构造这张白纸
this.add(c);//将这张白纸,铺在窗体上
this.setSize(500,550);//设置窗体大小
this.setTitle("中国象棋");//设置标题栏
this.setResizable(false);//不能改变大小
this.setLocationRelativeTo(null);//设置窗体剧中显示
this.setVisible(true);//设置窗体可见
this.setDefaultCloseOperation(EXIT_ON_CLOSE);//设置窗体的关闭方式}
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
//创建此窗体
newGui();}}
packagecom.game;
importjava.awt.Canvas;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.Point;
importjava.awt.event.MouseEvent;
importjava.awt.event.MouseListener;
/**
*自定义一个画布类,必须是系统Canvas类的子类
*本类就是一个画布==》一张白纸
*/
publicclassMyCanvaseextendsCanvasimplementsMouseListener{
//定义棋子数组,1-7(红方),8-14(黑方),无子:
0
privateint[][]allChessMan=newint[10][9];
privateintturn;
privateintmyturn;
privateinttemp;
privatePointtp;
publicMyCanvase()
{//设置纸的背景颜色
this.setBackground(newColor(100,124,45));
//初始化棋盘
this.addMouseListener(this);
this.init();}
publicvoidinit()
{//初始化棋盘中的棋子
//1-7(红方):
车马相士将炮兵
this.turn=1;
this.myturn=0;
this.temp=0;
this.tp=newPoint(8,9);
this.allChessMan[0][0]=1;
this.allChessMan[0][1]=2;
this.allChessMan[0][2]=3;
this.allChessMan[0][3]=4;
this.allChessMan[0][4]=5;
this.allChessMan[0][5]=4;
this.allChessMan[0][6]=3;
this.allChessMan[0][7]=2;
this.allChessMan[0][8]=1;
this.allChessMan[2][1]=6;
this.allChessMan[2][7]=6;
this.allChessMan[3][0]=7;
this.allChessMan[3][2]=7;
this.allChessMan[3][4]=7;
this.allChessMan[3][6]=7;
this.allChessMan[3][8]=7;
this.allChessMan[9][0]=8;
this.allChessMan[9][1]=9;
this.allChessMan[9][2]=10;
this.allChessMan[9][3]=11;
this.allChessMan[9][4]=12;
this.allChessMan[9][5]=11;
this.allChessMan[9][6]=10;
this.allChessMan[9][7]=9;
this.allChessMan[9][8]=8;
this.allChessMan[7][1]=13;
this.allChessMan[7][7]=13;
this.allChessMan[6][0]=14;
this.allChessMan[6][2]=14;
this.allChessMan[6][4]=14;
this.allChessMan[6][6]=14;
this.allChessMan[6][8]=14;}
publicvoidfixd(inti,intj,Graphicsg)
{
g.drawLine(i-8,j-16,i-8,j-8);
g.drawLine(i-8,j+16,i-8,j+8);
g.drawLine(i+8,j-16,i+8,j-8);
g.drawLine(i+8,j+16,i+8,j+8);
g.drawLine(i-16,j-8,i-8,j-8);
g.drawLine(i+16,j-8,i+8,j-8);
g.drawLine(i-16,j+8,i-8,j+8);
g.drawLine(i+16,j+8,i+8,j+8);}
//屏幕上每个横向的9个点,每个竖向的10个点,都有可能出现棋子
//程序=数据结构+算法
//问题=用一种数据结构,把要操作的东西装起来
//+
//在这个装下了东西的口袋中怎么操作
//通过分析发现:
每个点上一共有15种状态,无子|有子
//有子:
1-7(红方),8-14(黑方),无子:
0
//横有9个点,竖有10个点,一共有90个点
//90个点==10行9列的整型数组
//棋盘上的棋子,完全依赖这个棋子数组来画
for(introw=0;row{
for(intcol=0;col{
//if(this.allChessMan[row][col]==0)//无子,不需要画什么
if(this.allChessMan[row][col]!
=0)//有子,调用画棋子方法,单独画出这个棋子
this.drawChessMan(this.allChessMan[row][col],row,col,g);}}}
/**
*根据数组中的值,在棋盘的相应位置,画出相应的棋子
*@paramval:
棋子的值
*@paramrow:
棋子的行坐标
*@paramrow:
棋子的列坐标
*/
publicvoiddrawChessMan(intval,introw,intcol,Graphicsg)
{
intx,y;
Stringc[]={"车","马","相","士","帅","炮","兵","車","馬","象","仕","将","炮","卒"};
//将数组中的下标==》棋盘上的坐标
//0,0=>50,503,1=>100,2001,2=>150,100
//row=>ycol=>x
y=row*50+25;
x=col*50+25;
publicPointchg(Pointx)//转换棋盘坐标为数组坐标
{
inti,tempx,tempy;
//Pointk=null;
i=x.x%50;
//System.out.println("sd"+i);
if(i<25)
{//System.out.println("wii"+x.x);
//k.x=x.x-i;
//System.out.println(k.x);
tempx=x.x-i;
}
else{tempx=x.x-i+50;}
i=x.y%50;
if(i<25)
{
tempy=x.y-i;}
else{tempy=x.y-i+50;}
tempx=tempx/50-1;
tempy=tempy/50-1;
Pointk=newPoint(tempx,tempy);
//k.setLocation(tempx,tempy);
//System.out.println(k.x+"sd"+k.y);
returnk;
}
//判断是否为已方棋子
publicintown(Pointx){
if(this.allChessMan[x.y][x.x]==0)return0;
elseif((this.turn==0&&this.allChessMan[x.y][x.x]<8)||(this.turn==1&&this.allChessMan[x.y][x.x]>7))
return1;
else
return2;}
//各种棋子的移动方式
//车
publicintzhu(Pointx)
{
if(jg(x,this.tp)==0)return1;
return0;}
//马
publicintma(Pointx)
{
inti,j;
if(dist(x,this.tp)==5){
i=x.x-this.tp.x;
i=i*i;
if(i==1){
j=x.y+1;
if(j>this.tp.y)j=x.y-1;
if(this.allChessMan[j][this.tp.x]==0)return1;}
else{
j=x.x+1;
if(j>this.tp.x)j=x.x-1;
if(this.allChessMan[this.tp.y][j]==0)return1;}}
return0;}
//相
publicintxiang(Pointx){
inti,j;
if(this.turn==0&&x.y>4)return0;
if(this.turn==1&&x.y<5)return0;
if(dist(x,this.tp)==8){
i=x.x+this.tp.x;
j=x.y+this.t