五子棋设计说明何家俊汇编.docx
《五子棋设计说明何家俊汇编.docx》由会员分享,可在线阅读,更多相关《五子棋设计说明何家俊汇编.docx(14页珍藏版)》请在冰豆网上搜索。
五子棋设计说明何家俊汇编
西安财经学院
实践教学活动周登记表
姓名:
何佳俊
学号:
_1005170408
专业:
_计算机科学与技术
院系:
_信息学院
本校指导教师:
王瑞____
实践单位指导教师:
___________
西安财经学院教务处制
实践教学开展时间
2012年7月9日——2012年7月20日
实践形式(在选项后打√)
集中
分散
√
实践单位
实践地点
本校
指导教师
王瑞
职称
讲师
二级学院、系
信息学院
实习单位
指导教师
职称
职务
所在单位
实践内容及收获
(由学生本人填写,主要包括:
具体实践内容、成果形式、主要收获等)
通过合作完成五子棋对弈系统的后,我们发现自己在进行软件开发方面提高不少,同时积极利用所学到的新技术用于自己的设计开发过程。
另外,在整个开发的过程中,时间也比较仓促。
因此,该系统必然会存在一些缺陷和不足。
如:
没有讨论五子棋禁手的问题。
另一个就是电脑按即定的算法去与玩家下子。
这种算法有点“固定”。
不太会变,玩家若是仔细观察,可以掌握其规律。
还有就是界面不是很华丽。
有待改进。
实践单位意见
单位盖章:
年月日
成绩
评定
(综合评语)
成绩:
指导教师签字:
、
年月日
系意见
签字(盖章):
年月日
二级学院意见
签字(盖章):
年月日
注:
1.此表在下一学期开学一周内交给指导教师。
2.实践成果附后。
3.实习内容收获填写不下,可附页。
4.以个人社会调查、参加校内实践活动等没有到单位实践,不需填写实践单位意见。
5.成绩分为优秀、良好、中等、合格、不合格,共五级。
6.本表由二级学院存档。
本科生实践教学活动周实践教学成果
成果形式:
实践报告+系统
成果名称:
_____五子棋游戏设计_________
学生姓名:
何佳俊
学号:
1005170408
专业:
计算机科学与技术
班级:
计本1004
指导教师:
王瑞
完成时间:
2012年7月22日
1.1总体分析
基于本游戏,首先得为整个棋盘建立一张表格用以记录棋子信息,我们使用一个10*10的二维数组Table[10][10](10*10是五子棋棋盘的大小),数组的每一个元素对应棋盘上的一个交叉点,用‘0’表示空位、‘1’代表己方的子、‘2’代表对方的子;这张表也是今后分析的基础。
在此之后还要为两个玩家双方各建立一张棋型表Computer[10][10][4]和Player[10][10][4],用来存放棋型数据。
1.2初始化
首先,建立盘面数组Table[10][10]、对战双方的棋型表Computer[10][10][4]和Player[10][10][4]并将它们清零以备使用;然后初始化显示器、鼠等输入输出设备并在屏幕上画出棋盘(棋盘可以不显示)。
1.3主循环控制模块
控制下棋顺序,当轮到某方下子时,负责将程序转到相应的模块中去,主要担当一个调度者的角色。
1.4玩家下子
当轮到玩家下时,您通过键盘或鼠标在棋盘上落子,程序会根据该点的位置,在Table[10][10]数组的相应地方记录0,以表明该子是玩家下的。
元素值2表示空,1设置为计算机
1.5盘面分析填写棋型表
在下五子棋时,一定会先根据棋盘上的情况,找出当前最重要的一些点位,然后再在其中选择落子点。
先来分析己方的棋型,从棋盘左上角出发,向右逐行搜索,当遇到一个空白点时,以它为中心向左挨个查找,如果遇到己方的子则记录然后继续,如果遇到对方的子、空白点或边界就停止查找。
左边完成后再向右进行同样的操作;最后把左右两边的记录合并起来,得到的数据就是该点横向上的棋型,然后把棋型的编号填入到Computer[x][y][n]中就行了(x、y代表坐标,n=0、1、2、3分别代表横、竖、左斜、右斜四个方向)。
而其他三个方向的棋型也可用同样的方法得到,当搜索完整张棋盘后,己方棋型表也就填写完毕了。
然后再用同样的方法填写对方棋型表。
1.6对方下子
有了上面填写的两张棋型表,就是遍历棋型表Computer[10][10][4]和Player[10][10][4]找出其中数值最大的一点,在该点下子即可。
如果在这儿下子将会形成对手不得不防守的棋型;那么下一步对手就会照您的思路下子来防守您,如此一来便完成了第一步的预测。
这时再调用模块4对预测后的棋进行盘面分析,就可预测出第二步、第三步……
进攻不成的话就得考虑防守了,将自己和对手调换一下位置,然后用上面的方法来预测对手的棋,这样既可以防住对手巧妙的攻击,又能待机发动反击
1.7胜负判断
务须多言,某方形成五子连即获胜
2.1功能模块图
图2.1功能模块图
2.2功能说明
该五子棋程序基本上实现了五子棋的游戏功能,有双方下棋的界面及最终判定结果的界面。
同时该游戏采用二维坐标实现,明了易懂,方便玩家在游戏过程中的基本操作,使游戏更加简便。
在细节方面,该系统提供实时存储功能,随时记录为完成的游戏,使用户可以很好的处理意外中断的情况。
该游戏基本实现了游戏的一些要求和特征。
在游戏的源程序及文档方面,我们也严格遵守软件工程思想,立足实验要求,确定任务,需求分析,设计和编码,每个步骤力求清晰易懂。
原代码注释详尽,各功能模块功能分明,可移植性强。
当然该系统也有很多不足的地方,第一次进行独立的课程设计,也有很多细节方面是考虑到的,这款游戏也是在不断的调试和修改中产生和完善的。
希望老师能够指出不足,帮助我不断提高。
第三章系统设计
3.1流程图
图3.1流程图
3.2流程图说明
本程序定义了各种操作函数、各种状态判定宏,思想明确,思路清晰。
各个判断选择了不同路径,因此继续进行或输出结果。
程序中,“循环”的利用非常直接和清晰,双方交替下棋,因此循环往复。
最终决出胜负或最终平局。
分析时,也考虑了许多种情况,针对各个情况均作出了相对措施和解决方案。
程序采用循环进行双方交替下棋,并进行了很多判断。
首先判断棋盘是否已满,若棋盘已满,则输出平局,结束游戏;若棋盘未满,则继续进行。
然后判断“0”方是否胜出,若“0”方获胜,则输出“0”方获胜,结束游戏;若“0”方没有获胜,则继续进行。
再判断“x”方是否获胜,若“x”方获胜,则输出“x”方获胜,结束游戏;若“x”方没有获胜,则继续进行。
回到“首先”的判断。
如此循环……
第四章运行结果
图4.1运行结果初始图
图4.2游戏过程图
图4.3游戏进行图
总结
我们小组通过对五子棋小游戏的编写,增加了对编写程序的兴趣,尤其是利用C++,不禁惊叹于微软编程人员为我们提供了那么多可以直接使用的类资源。
期间,通过查资料,与组员之间交流,学到了许多课堂上所没有的新知识.编写此程序还需要我们有良好的程序素养,即书写习惯,添加注释,方便日后查看理解甚至修改。
期间,需要设置好多变量,分别存储棋子的标志
要十分完善的编写这个程序的确有点困难,这要求我们必须多花心思与精力,多与别人交流探讨,多查处自己程序的bug,最最重要的是自己一定要有耐心,努力去完成。
参考文献
[1]C++编程思想,BruceEckel著,刘宗田/邢大红/孙慧杰等译,机械工业出版社
[2]21天学通C++,JesseLiberty著,康博创作室译,人民邮电出版社
[3]C++标准程序库,NicolaiM.Josuttis著,侯捷/孟岩译,华中科技大学出版社
[4]Windows程序设计,CharlesPetzold著,北京博彦科技发展有限公司译,北京大学出版社
[5]VisualC++.NET网络编程,易君编著,中国铁道出版社
[6]博弈树搜索
http:
//202.113.96.26/wlkc/rengongzhineng/rengongzhineng/kejian/AI/Ai/chapter3/33.htm
[7]五子棋的核心算法,蝈蝈俊.net
源代码
//canvasFrame.cpp:
implementationfile
//
#include"stdafx.h"
#include"canvasr.h"
#include"canvasFrame.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//canvasFramemessagehandlers
voidcanvasFrame:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
if(!
over)
if(player)
{
if(point.x<400&&point.y<400)//确定按下左键的位置在棋盘范围内
{
m=(int)floor(point.x/40);//根据按下左键的位置(point.x,point.y)来计算该点所在格子的索引值m,n,以便在该位置填上棋子
n=(int)floor(point.y/40);
if(board[m][n]==2)
{
board[m][n]=0;//表示该格子上填入的是玩家的棋子
pcount++;//累计玩家棋子总数
if((ccount==50)&&(pcount==50))//判断目前玩家与计算机的棋子总数是否都等于50,如果是则表示战成平手
{
tie=true;
over=true;
}
for(i=0;i<192;i++)//判断玩家所下的棋子在哪些可能获胜的组合中,并累加这些可能获胜的组合中所填入棋子数
{
if(ptable[m][n][i]&&win[0][i]!
=7)//判断所下的旗子是否在获胜组合(ptable[m][n][i])中,而且win[0][i]不等于7,win[0][i]表示玩家在第i种组合中所填入的旗子数,若在该获胜组合中已不能取胜,则将其值置为7
win[0][i]++;//当所下旗子在某一可能获胜组合中时,就将该组合中填入的棋子数加1
if(ctable[m][n][i])//当玩家在(m,n)位置填上棋子后,将计算机该位置上的取胜几率设为不可能
{
ctable[m][n][i]=false;
win[1][i]=7;
}
}
player=false;//换计算机下
computer=true;
}
}
}
CFrameWnd:
:
OnLButtonDown(nFlags,point);
}
intcanvasFrame:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CFrameWnd:
:
OnCreate(lpCreateStruct)==-1)
return-1;
SetTimer(1,500,NULL);
return0;
}
voidcanvasFrame:
:
OnTimer(UINTnIDEvent)
{
CClientDCdc(this);
if(!
over)
{
if(computer)//计算机下棋
ComTurn();
for(i=0;i<=1;i++)
for(j=0;j<192;j++)
{
if(win[i][j]==5)//玩家获胜
if(i==0)
{
pwin=true;
over=true;
break;
}
else//计算机获胜
{
cwin=true;
over=true;
break;
}
if(over)
break;
}
dc.TextOut(85,400," 该您下了.. ");
}
mdc1->SelectObject(bgbmp);
mdc->BitBlt(0,0,400,400,mdc1,0,0,SRCCOPY);
for(i=0;i<=9;i++)
for(j=0;j<=9;j++)
{
if(board[i][j]==0)//贴上玩家棋子
{
mdc1->SelectObject(green);
mdc->BitBlt(i*40+2,j*40+2,36,36,mdc1,0,0,SRCCOPY);
}
if(board[i][j]==1)//贴上计算机棋子
{
mdc1->SelectObject(purple);
mdc->BitBlt(i*40+2,j*40+2,36,36,mdc1,0,0,SRCCOPY);
}
}
dc.BitBlt(0,0,400,400,mdc,0,0,SRCCOPY);
if(pwin)
dc.TextOut(85,400,"您赢了!
按下F1可重新进行游戏..");
if(cwin)
dc.TextOut(85,400,"电脑赢了!
按下F1可重新进行游戏..");
if(tie)
dc.TextOut(85,400,"不分胜负!
按下F1可重新进行游戏..");
CFrameWnd:
:
OnTimer(nIDEvent);
}