Visual C ++MFC框架的五子棋 软件应用技术Word文档下载推荐.docx
《Visual C ++MFC框架的五子棋 软件应用技术Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Visual C ++MFC框架的五子棋 软件应用技术Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
![Visual C ++MFC框架的五子棋 软件应用技术Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-12/12/28ff7807-5600-468a-9421-cc62bff13940/28ff7807-5600-468a-9421-cc62bff139401.gif)
3.4子功能46
3.5子功能57
4、界面要求7
5、测试方案7
6功能设计8
6.1类的关系描述8
6.2类的设计8
7使用指南14
8总结15
9参考文献16
一引言
1.1编写目的
本文档编写的目的是为了说明我所编写的五子棋软件具有的基本功能及其实现方法以及作为用户操作手册,方便用户使用我所编写的五子棋软件。
1.2读者对象
本文档中关于具体实现部分涉及到C++面向对象编程技术和数据结构中有关模式匹配的知识,对于有这方面知识的用户可以读读,如果关于实现有什么建议或意见,可以跟我联系。
而对于一般的用户则完全可以跳过这部分内容,直接阅读有关操作的使用说明。
1.3软件项目概述
简要说明关于本软件项目的:
●项目名称:
实用五子棋双人对战程序编写
●简称:
五子棋
●项目代号:
200306020034
●软件项目的大致功能和性能要求
基本功能如下:
1.记录游戏双方的落子过程,允许悔棋;
2.实现保存棋谱和根据棋谱复盘的功能;
3.判断双方输赢,先走出五子连珠的一方赢;
4.响应用户鼠标消息,并显示棋盘信息;
5.先下者落子时不允许走禁手。
2任务概述
2.1目标
这个软件的开发主要是为了使我自己更好地掌握C++程序设计技能,特别是目前常用的C++程序设计环境,VisualC++6.0,通过课题实践的方式让我初步掌握C++和MFC编程的有关知识,为学习后序开设的算法设计与分析、数据库、软件工程等课程打下必要的基础。
2.2软件的开发和运行环境
借助MicrosoftvisualC++6.0编译器,在各种电脑上可运行,硬件要求能运行MicrosoftvisualC++6.0即可。
2.3用户特征
用户主要是对五子棋有一定爱好的人或者对编程感兴趣的人士。
而维护人员则要求掌握MicrosoftvisualC++6.0语言编程,熟悉MFC的各种操作,并且具有一定数据结构知识的人。
2.4假设与约束
软件开发要求8周内完成,经费为0.
功能包括能够记录游戏双方的落子过程,允许悔棋;
实现保存棋谱和根据棋谱复盘的功能;
判断双方输赢,先走出五子连珠的一方赢;
响应用户鼠标消息,并显示棋盘信息;
判断黑棋落子时不允许走禁手.
2.5进度要求
描述目标软件系统的开发进度
3、功能需求描述
功能要求:
a)正常落棋子,不会覆盖已有棋子。
b)悔棋,并记录悔棋过程,即悔棋数目和位置。
c)复盘,记录棋盘棋子的颜色,数目,位置,并能够一步步恢复棋盘,即重演落子过程。
d)对黑棋能够正确判断禁手。
e)判断黑白两方的胜负。
F)实现棋盘的保存。
即在停止运行程序一段时间后能够接着以前下的接着下。
3.1子功能1
打印棋盘
棋盘是19*19的方格棋盘,其中在(4,4),(4,16),(16,4),(16,16)处各打印一个小黑点。
棋盘背景色为黄色的类似桌面颜色。
3.2子功能2
下棋
记录双方落子的过程,黑方先下,而且先下者必须落子(10,10)位置。
下棋时为响应鼠标左键的点击。
当鼠标图标位于棋盘范围内时,每点一下,落子一个。
双方交替落子
3.3子功能3
悔棋
当一方点击位于工具栏中的悔棋图标时,将会进入悔棋界面,每点击一下,悔掉最近落子的一步,直到用户再次在棋盘界面内点击鼠标左键开始下棋为止。
3.4子功能4
复盘
该功能用于当一盘棋局结束后,重现双方下棋落子以及悔棋的过程。
该功能的控制位于控制栏的下棋菜单中,点击该菜单,在其下拉菜单中选择复盘,将进入复盘界面,将重现从开始到最后的落子或者悔棋过程,响应为鼠标点击,每点击鼠标一下,落子一下或者悔棋一步。
当复盘过程完成后,会弹出提示对话框,告诉用户复盘过程已完成。
3.5子功能5
保存
用于当用户在下棋过程中由于什么意外的原因要离开现场,而又想等会回来接着刚才的棋局继续下时,此时用户可以点击下棋菜单的子菜单中的保存。
当用户点击此项功能后,程序将会保存当前的棋盘,也将保存以前的落子过程。
当用户下次再运行五子棋程序时,打印出来的棋盘是刚才下过的棋盘,用户可以接着刚才的棋盘继续下。
4、界面要求
描述用户对目标软件系统的界面要求,可在此处描述目标软件系统的原型。
5、测试方案
1:
运行程序,棋盘正确与否。
2:
画棋子时,是否为先黑后白,并且不同的棋子不会发生重叠现象。
3:
能否正确判断五子连珠,并提示游戏胜利方同时结束游戏。
4:
能否正确实现悔棋,撤消,复盘及重下等功能。
1.5:
能否正确判断黑子禁手,禁手包括下面几种情况。
五子连珠的禁手包括以下几种情况:
三三禁手三三禁手四四禁手
四四禁手四四禁手四四禁手
四三三禁手长连禁手
6功能设计
6.1类的关系描述
structPOINTME用于记录下棋过程的点类。
classchess为棋盘类。
其中包括记录下棋过程的POINTME类型数组Process[800]和记录棋盘当前状态的ChessBoard[19][19]数组。
classCWzqView为用于输出棋盘信息的类。
用于打印棋盘和落子,以及显示相关的悔棋过程和提供一些辅助性的对话框,用来实现人机交流。
classCWzqDoc为用于实现棋盘的一些基本属性的类。
在该类中规定了棋盘的大小,为19*19大小。
structPOINTME包含于classchess内,用于其中来记录下棋落子的过程,在CWzqView.cpp中声明了一个chess类对象C用于下棋。
ClassCWzqView只是用于对classchess进行操作,使其能够进行人机交互。
classCWzqDoc用于对classCWzqView的一些基本属性进行描述,如打印棋盘的方格数大小。
6.2类的设计
structPOINTME
{
CPointpoint;
//落棋点的坐标
intflag;
//该棋的类别:
-1,未下过;
0,现在有子;
2,以前下过,现在已悔棋
intcolor;
//0,黑棋;
1,白棋;
};
定义structPOINTME 的作用是为了更好的记录下棋和悔棋的过程以便于实现复盘和悔棋的功能。
CPointpoint记录落棋点的坐标;
intflag用来记录point点的状态,其不同数值分别表示:
-1,point点未下过;
0,point点现在有子;
2,point点以前下过,现在已悔棋。
intcolor用于记录当point点有子或者以前下过子现在已经悔棋了,该子的颜色。
其不同的颜色分别表示:
0,黑棋;
Classchess:
其具体属性包括:
public:
intCcount;
//记录包括悔棋在内的所有步数
intRcount;
//记录复盘过程中走的步数
POINTMEProcess[800];
//记录下棋的过程
intChessBoard[19][19];
//3,未下;
0,黑棋;
intDChessBoard[19][19];
//棋盘的表示的拷贝
intlastColor;
//最后一个棋的颜色;
boolRecover;
//标志是否处于复盘状态
private:
charT[4][10];
//分别用于存储对四个不同的方向进行扫描时的结果
char*BFive;
//黑五连时的字符串00000
char*WFive;
//白五连时的字符串11111
char*Four;
//活四
char*SFour[5];
//五种冲四
char*Three[3];
//三种活三
char*Six;
//六腐
char*Lian;
//长联
FILE*f;
//文件指针,用于保存
首先,我有必要说明我的棋盘存储方式。
我用到intChessBoard[19][19]来存储棋盘信息,其中ChessBoard[i][j]的不同数值来对应表示棋盘上(i,j)点的棋子信息。
数值为3,表示该点未下子;
为0,表示该点下了黑棋;
为1,表示该点下了白棋。
之所以用3来表示该点未落子,是为了更方便地实现后面的字符串模式匹配算法。
为了实现对棋盘信息的有效保护,我设置了intDChessBoard[19][19]数组用来做为intChessBoard[19][19]的拷贝,主要用于可能修改需要修改棋盘的场合。
POINTMEProcess[800]为用来记录双方下棋落子的过程,Process[]数组的下标即表示第几步。
设置这个数组主要是为了方便复盘,复盘时只需从头到尾读取这个数组,根据其中的不同信息做出不同的打印动作即可。
每次下棋落子或悔棋后都在Process[]数组中增加一项。
intCcount用于记录包括悔棋在内的所有步数
intRcount用于记录复盘过程中走的步数
intlastColor;
用来记录最后一个棋的颜色;
boolRecover用来标志是否处于复盘状态
下面分别解释私有数据中字符串的功能:
这里是我最为我的程序感到骄傲的部分。
它成功的运用了模式匹配的算法思想解决了禁手和胜负的判断问题。
charT[4][10]用于存储voidScan(CPointt);
每落一子即对其四个不同的方向进行扫描时所得的结果。
在胜负的判断和禁手的判断中我用到了字符串模式匹配的思想。
即用char*BFive 来存储黑五连时的字符串,字符串中的具体内容是00000;
用char*WFive来存储白五连时的字符串,字符串中的具体内容是11111;
用char*Four来存储黑子形成活四时的情形,字符串中的具体内容是300003;
用char*SFour[5]来存储五种不同的冲四,其内存储的内容分别为:
SFour[0]="
100003"
;
SFour[1]="
300001"
SFour[2]="
00030"
SFour[3]="
00300"
SFour[4]="
03000"
用char*Three[3]来存储三种不同的活三,其内存储的内容分别为:
Three[0]="
30003"
Three[1]="
300303"
Three[2]="
303003"
用char*Six来存储六腐,其内存储的内容为:
Six="
1300031"
用char*Lian来存储长联禁手,具体内容为:
Lian="
000000"
FILE*f是文件指针,用于指向保存时用的文件。
基本方法:
chess();
virtual~chess();
boolIsPre(CPointtemp);
//判断是否是以前下过的点
voidScan(CPointt);
//落子时的扫描函数,每落一子即对其四个不同的方向进行扫描
intJudge(CPointt);
//判断胜负
intProhibit(CPointt);
//判断禁手
intFind(char*object,char*target);
//KMP模式匹配
voidRestore();
//保存函数
Next(char*s,int*next);
chess()和virtual~chess()分别为classchess的构造函数和析构函数。
在 chess()函数内首先判断是处于开始状态还是处于保存过棋盘后继续状态,具体判断是通过看文件指针f是否为NULL来判断。
当其为NULL时初始化棋盘时,按照没下过棋来初始化。
如果其不为NULL,则从文件中读取相应的数据来初始化。
boolIsPre(CPointtemp)是用来判断是否是以前下过的点的函数,如果是则返回true,否则返回false.
voidScan(CPointt),落子时的扫描函数,每落一子即对其四个不同的方向进行扫描。
每落子的四个不同方向进行扫描,扫描以落子点为中心的前后四个点的状态。
扫描得到的结果存储在charT[4][10]数组。
intJudge(CPointt),判断胜负函数,每落一子通过对其调用Scan(CPointt)函数扫描其四个方向,将其结果通过模式匹配与char*BFive和char*WFive进行匹配,如果成功,即为有一方胜利。
返回1,否则返回-1。
intProhibit(CPointt),判断禁手函数。
共能判断几种简单的禁手,而对于复杂的嵌套禁手将无能为力,这是我这个程序的不足之处。
几中简单的禁手分别为:
voidRestore(),保存函数。
在用户选择保存后调用此函数,将当前棋盘的内容和下子过程记录进文件指针FILE*f所指文件。
其判断原理与判断胜负一样都是通过对黑方落子的四个方向进行扫描,将其结果存储于charT[4][10],然后通过模式匹配寻找在其四个方向形成了一些什么样的子力。
对于形成双活三,双活四,一活四一冲四,长连的判为禁手,同时也注意到一些不是禁手的容易误判,例如六腐。
intFind(char*object,char*target),KMP模式匹配函数,见参考书籍[1]。
Next(char*s,int*next),KMP模式匹配中next[]数组产生函数,见参考书籍[1]。
classCWzqDoc:
publicCDocument
在其中加入如下操作说明:
intnGetBoardRowNum()const;
voidvSetBoardRowNum(intnRows);
CPointptGetPiecePos()const;
voidvSetPiecePos(CPointpiecePos);
intnGetBoardRowNum,返回BoardRowNum的大小,即返回棋盘的大小。
voidvSetBoardRowNum(intnRows),设置BoardRowNum的大小,即棋盘的大小。
CPointptGetPiecePos(),返回当前点的坐标,函数返回值类型是VC内部定义的类型CPoint.表示棋盘上点的坐标。
voidvSetPiecePos(CPointpiecePos),设置当前点的坐标为CPointpiecePos的点。
classCWzqView:
publicCView
加入如下操作说明:
protected:
voidvDrawPiece(POINTMEtemp,CDC*pDC);
CPointptConvertVP2BP(CPointpointView)const;
CPointptConvertBP2VP(CPointpointView)const;
CPointptConvertVP2BP(intx,inty)const;
CPointptConvertBP2VP(intx,inty)const;
BOOLbPointInBoard(CPointpointView,intnBoardRowNum)const;
在这里还对系统的两个重要的函数进行了修改。
其中一个是virtualvoidOnDraw(CDC*pDC),在它里面加入了有关绘制棋盘和下棋过程的实现。
另一个是afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint),使其能够在下棋过程中响应鼠标的左键点击和在复盘过程中响应鼠标的点击。
voidvDrawPiece(POINTMEtemp,CDC*pDC),在POINTMEtemp点画图,根据temp所包含的不同信息,进行不同的动作,如画黑棋,白棋和悔棋,(即画与背景颜色一样的棋子,然后再在刚才画过的区域画两条线)
CPointptConvertVP2BP(CPointpointView),工具函数。
把视频上的象素点转变成为棋盘上的点。
CPointptConvertBP2VP(CPointpointView),工具函数。
将棋盘上的点转变成视频上的象素点。
CPointptConvertVP2BP(intx,inty),重载的工具函数。
将视频上(x,y)
CPointptConvertBP2VP(intx,inty),重载的工具函数。
BOOLbPointInBoard(CPointpointView,intnBoardRowNum),判断CPointpointView是否在棋盘内部的函数。
7使用指南
软件无须安装,只要求安装有MicrosoftvisualC++6.0即可,使用时,运
行源程序即可。
菜单中,除下棋菜单外,其它菜单无须或者无法使用。
下棋菜单中的悔棋,允许下棋者悔棋,如果悔棋错误,并可点击撤消菜单撤消悔棋,重下菜单重新开始一局五子棋对战,复盘菜单根据棋盘记录恢复棋盘。
8总结
通过本次实践使我MFC编程有了一定的认识,提高了我对于C++面向对象程序设计功能优点的认识度。
由于是第一次接触到MFC编程,所以有很多概念不是很明白,在进行实践活动的过程中,我又自学了一些关于MFC编程的书籍,了解了进行MFC编程的一些深层次的问题,比如,对于MFC主要是一个消息驱动编程思想的认识。
在自学的过程中,进一步提高了我寻找信息,和筛选信息的能力。
也同时提高了我的自学能力。
但是在本次实践活动中,由于主观和客观的各种因素,我没能完成人机对战和网络对战的编写,自己感觉很是遗憾。
不过,我还是感到庆幸的是,通过这次实践活动,把我带进MFC编程这个美丽的,充满魅力的殿堂。
师傅领进门,修行在个人。
在这次实践活动结束以后,就完全是修行在个人了,我感谢给我指明方向,带我进入这个编程的殿堂的人,我也将在这个神奇,美丽的殿堂里慢慢学习。
事在人为。
参考文献
[1]CharlesPetzold,《ProgrammingWindows》,清华大学出版社,2010
[2]BruceEckel,《ThinkinginC++》,机械工业出版社,2000
[3]侯捷,《深入浅出MFC》,华中科技大学出版社,2005
[4]孙鑫,《VC++从入门到精通》,机械工业出版社,2008
[5]姚领田,《精通MFC程序设计》,人民邮电出版社,2006