百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

MFC编写的五子棋源程序,包含详细的设计文档,软件工程课程设计

liebian365 2024-10-14 22:13 29 浏览 0 评论

文档编号:项目名称 – 版本

项目名称

课程实践报告书

制订人:

号:

2005年 5月 14日


文档变更历史记录

序号

变更日期

变更人员

变更内容详情描述

版本

1

2001/11/1

张三

创建

1.0

2

2001/11/15

王五

增加了**需求描述(见**章节)

1.1








































































目录

目录33

1、引言44

1.1 编写目的44

1.2 读者对象44

1.3 软件项目概述44

1.4 文档概述44

1.5 定义44

1.6 参考资料44

2、任务概述55

2.1目标55

2.2软件的开发和运行环境55

2.3 用户特征55

2.4 假设与约束55

2.5 进度要求55

2.6验收要求66

3、功能需求描述77

3.1 子功能171717

3.2 子功能272727

…77

4、界面要求77

5、测试方案77

6、功能设计88

6.1类的关系描述88

6.2类的设计88

7、使用指南88

8、维护接口88

9、总结88


1、引言

1.1 编写目的

本文档编写的目的是为了说明我所编写的五子棋软件具有的基本功能及其实现方法以及作为用户操作手册,方便用户使用我所编写的五子棋软件。

1.2 读者对象

本文档中关于具体实现部分涉及到C++面向对象编程技术和数据结构中有关模式匹配的知识,对于有这方面知识的用户可以读读,如果关于实现有什么建议或意见,可以跟我联系,电子邮箱 mash06@sina.com。而对于一般的用户则完全可以跳过这部分内容,直接阅读有关操作的使用说明。

1.3 软件项目概述

简要说明关于本软件项目的:

  • 项目名称:实用五子棋双人对战程序编写
  • 简称:五子棋
  • 项目代号:200306020034
  • 软件项目的大致功能和性能要求

基本功能如下:

1.记录游戏双方的落子过程,允许悔棋;

2.实现保存棋谱和根据棋谱复盘的功能;

3.判断双方输赢,先走出五子连珠的一方赢;

4.响应用户鼠标消息,并显示棋盘信息;

5.先下者落子时不允许走禁手。

1.4 文档概述

简要说明本文档的大致内容及其组织结构

1.5 定义

模式匹配:在一个字符串中寻找一给定字符串,如果存在,返回在其中的起始位置。否则返回-1。

1.6 参考资料

以列表或排序的方式给出重要的参考资料的名称、作者、单位、出版日期等信息。

[1]《数据结构 C++语言描述(第二版)》熊岳山 陈怀义

国防科技大学出版社 2004年1月


2、任务概述

2.1目标

这个软件的开发主要是为了使我自己更好地掌握C++程序设计技能,特别是目前常用的C++程序设计环境,Visual C++6.0,通过课题实践的方式让我初步掌握C++和MFC编程的有关知识,为学习后序开设的算法设计与分析、数据库、软件工程等课程打下必要的基础。

2.2软件的开发和运行环境

借助Microsoft visual C++6.0编译器,在各种电脑上可运行,硬件要求能运行Microsoft visual C++6.0即可。

2.3 用户特征

用户主要是对五子棋有一定爱好的人或者对编程感兴趣的人士。

而维护人员则要求掌握Microsoft visual C++6.0语言编程,熟悉MFC的各种操作,并且具有一定数据结构知识的人。

2.4 假设与约束

软件开发要求8周内完成,经费为0.

功能包括能够记录游戏双方的落子过程,允许悔棋;实现保存棋谱和根据棋谱复盘的功能;判断双方输赢,先走出五子连珠的一方赢;响应用户鼠标消息,并显示棋盘信息;判断黑棋落子时不允许走禁手.

2.5 进度要求

描述目标软件系统的开发进度

2.6验收要求

要求无错误能正常运行,达到要求,并实现所要求功能。


3、功能需求描述

功能要求:

  1. 正常落棋子,不会覆盖已有棋子。
  2. 悔棋,并记录悔棋过程,即悔棋数目和位置。
  3. 复盘,记录棋盘棋子的颜色,数目,位置,并能够一步步恢复棋盘,即重演落子过程。

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类的关系描述

struct POINTME用于记录下棋过程的点类。

class chess 为棋盘类。其中包括记录下棋过程的POINTME 类型数组Process[800]和记录棋盘当前状态的ChessBoard[19][19]数组。

class CWzqView为用于输出棋盘信息的类。用于打印棋盘和落子,以及显示相关的悔棋过程和提供一些辅助性的对话框,用来实现人机交流。

class CWzqDoc 为用于实现棋盘的一些基本属性的类。在该类中规定了棋盘的大小,为19*19大小。

struct POINTME 包含于class chess内,用于其中来记录下棋落子的过程,在 CWzqView.cpp 中声明了一个chess类对象C 用于下棋。Class CWzqView只是用于 对class chess进行操作,使其能够进行人机交互。class CWzqDoc 用于对class CWzqView的一些基本属性进行描述,如打印棋盘的方格数大小。

6.2类的设计

struct POINTME

{

CPoint point; //落棋点的坐标

int flag; //该棋的类别:-1,未下过;0,现在有子;2,以前下过,现在已悔棋

int color; //0,黑棋;1,白棋;

};

定义struct POINTME 的作用是为了更好的记录下棋和悔棋的过程以便于实现复盘和悔棋的功能。CPoint point记录落棋点的坐标;int flag用来记录point点的状态,其不同数值分别表示:-1,point点未下过;0,point点现在有子;2,point点以前下过,现在已悔棋。int color 用于记录当point点有子或者以前下过子现在已经悔棋了,该子的颜色。其不同的颜色分别表示: 0,黑棋;1,白棋;

Class chess :

其具体属性包括:

public:

int Ccount;//记录包括悔棋在内的所有步数

int Rcount;//记录复盘过程中走的步数

POINTME Process[800];//记录下棋的过程

int ChessBoard[19][19]; //3,未下;0,黑棋;1,白棋;

int DChessBoard[19][19]; //棋盘的表示的拷贝

int lastColor;//最后一个棋的颜色;

bool Recover; //标志是否处于复盘状态

private:

char T[4][10];//分别用于存储对四个不同的方向进行扫描时的结果

char* BFive; //黑五连时的字符串00000

char* WFive; //白五连时的字符串11111

char* Four; //活四

char* SFour[5];//五种冲四

char* Three[3];//三种活三

char* Six;//六腐

char* Lian;//长联

FILE* f;//文件指针,用于保存

首先,我有必要说明我的棋盘存储方式。

我用到int ChessBoard[19][19]来存储棋盘信息,其中ChessBoard[i][j]的不同数值来对应表示棋盘上(i,j)点的棋子信息。数值为3,表示该点未下子;为0,表示该点下了黑棋;为1,表示该点下了白棋。之所以用3来表示该点未落子,是为了更方便地实现后面的字符串模式匹配算法。

为了实现对棋盘信息的有效保护,我设置了int DChessBoard[19][19]数组用来做为 int ChessBoard[19][19]的拷贝,主要用于可能修改需要修改棋盘的场合。

POINTME Process[800]为用来记录双方下棋落子的过程,Process[]数组的下标即表示第几步。设置这个数组主要是为了方便复盘,复盘时只需从头到尾读取这个数组,根据其中的不同信息做出不同的打印动作即可。每次下棋落子或悔棋后都在Process[]数组中增加一项。

int Ccount用于记录包括悔棋在内的所有步数

int Rcount用于记录复盘过程中走的步数

int lastColor;用来记录最后一个棋的颜色;

bool Recover用来标志是否处于复盘状态

下面分别解释私有数据中字符串的功能:这里是我最为我的程序感到骄傲的部分。它成功的运用了模式匹配的算法思想解决了禁手和胜负的判断问题。

char T[4][10]用于存储void Scan(CPoint t);每落一子即对其四个不同的方向进行扫描时所得的结果。

在胜负的判断和禁手的判断中我用到了字符串模式匹配的思想。即用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();

bool IsPre(CPoint temp);//判断是否是以前下过的点

void Scan(CPoint t);//落子时的扫描函数,每落一子即对其四个不同的方向进行扫描

int Judge(CPoint t); //判断胜负

int Prohibit(CPoint t);//判断禁手

int Find ( char * object, char* target);//KMP模式匹配

void Restore();//保存函数

Next (char * s, int * next);//KMP模式匹配

chess()和virtual ~chess()分别为class chess 的构造函数和析构函数。在 chess()函数内首先判断是处于开始状态还是处于保存过棋盘后继续状态,具体判断是通过看文件指针f是否为NULL来判断。当其为NULL时初始化棋盘时,按照没下过棋来初始化。如果其不为NULL,则从文件中读取相应的数据来初始化。

bool IsPre(CPoint temp)是用来判断是否是以前下过的点的函数,如果是则返回true ,否则返回false.

void Scan(CPoint t),落子时的扫描函数,每落一子即对其四个不同的方向进行扫描。每落子的四个不同方向进行扫描,扫描以落子点为中心的前后四个点的状态。扫描得到的结果存储在char T[4][10]数组。

int Judge(CPoint t),判断胜负函数,每落一子通过对其调用Scan(CPoint t)函数扫描其四个方向,将其结果通过模式匹配与char* BFive和char* WFive进行匹配,如果成功,即为有一方胜利。返回1,否则返回-1。

int Prohibit(CPoint t),判断禁手函数。共能判断几种简单的禁手,而对于复杂的嵌套禁手将无能为力,这是我这个程序的不足之处。几中简单的禁手分别为:

五子连珠的禁手包括以下几种情况:

三三禁手 三三禁手 四四禁手

四四禁手 四四禁手 四四禁手

四三三禁手 长连禁手

void Restore(),保存函数。在用户选择保存后调用此函数,将当前棋盘的内容和下子过程记录进文件指针FILE* f所指文件。

其判断原理与判断胜负一样都是通过对黑方落子的四个方向进行扫描,将其结果存储于char T[4][10],然后通过模式匹配寻找在其四个方向形成了一些什么样的子力。对于形成双活三,双活四,一活四一冲四,长连的判为禁手,同时也注意到一些不是禁手的容易误判,例如六腐。

int Find ( char * object, char* target),KMP模式匹配函数,见参考书籍[1]。

Next (char * s, int * next),KMP模式匹配中next[]数组产生函数,见参考书籍[1]。

class CWzqDoc : public CDocument

在其中加入如下操作说明:

public:

int nGetBoardRowNum() const;

void vSetBoardRowNum(int nRows);

CPoint ptGetPiecePos() const;

void vSetPiecePos(CPoint piecePos);

int nGetBoardRowNum,返回BoardRowNum的大小,即返回棋盘的大小。

void vSetBoardRowNum(int nRows),设置BoardRowNum的大小,即棋盘的大小。

CPoint ptGetPiecePos() ,返回当前点的坐标,函数返回值类型是VC内部定义的类型CPoint.表示棋盘上点的坐标。

void vSetPiecePos(CPoint piecePos),设置当前点的坐标为CPoint piecePos的点。

class CWzqView : public CView

加入如下操作说明:

protected:

void vDrawPiece(POINTME temp, CDC* pDC);

CPoint ptConvertVP2BP(CPoint pointView) const;

CPoint ptConvertBP2VP(CPoint pointView) const;

CPoint ptConvertVP2BP(int x, int y) const;

CPoint ptConvertBP2VP(int x, int y) const;

BOOL bPointInBoard(CPoint pointView, int nBoardRowNum) const;

在这里还对系统的两个重要的函数进行了修改。其中一个是virtual void OnDraw(CDC* pDC),在它里面加入了有关绘制棋盘和下棋过程的实现。

另一个是afx_msg void OnLButtonDown(UINT nFlags, CPoint point),使其能够在下棋过程中响应鼠标的左键点击和在复盘过程中响应鼠标的点击。

void vDrawPiece(POINTME temp, CDC* pDC),在POINTME temp点画图,根据temp 所包含的不同信息,进行不同的动作,如画黑棋,白棋和悔棋,(即画与背景颜色一样的棋子,然后再在刚才画过的区域画两条线)

CPoint ptConvertVP2BP(CPoint pointView) ,工具函数。把视频上的象素点转变成为棋盘上的点。

CPoint ptConvertBP2VP(CPoint pointView) ,工具函数。将棋盘上的点转变成视频上的象素点。

CPoint ptConvertVP2BP(int x, int y) ,重载的工具函数。将视频上(x,y)

CPoint ptConvertBP2VP(int x, int y) ,重载的工具函数。将棋盘上的点转变成视频上的象素点。

BOOL bPointInBoard(CPoint pointView, int nBoardRowNum) ,判断CPoint pointView 是否在棋盘内部的函数。

7、使用指南

软件无须安装,只要求安装有Microsoft visual C++6.0即可,使用时,运

行源程序即可。菜单中,除下棋菜单外,其它菜单无须或者无法使用。

下棋菜单中的悔棋,允许下棋者悔棋,如果悔棋错误,并可点击撤消菜单撤消悔棋,重下菜单重新开始一局五子棋对战,复盘菜单根据棋盘记录恢复棋盘。

8、维护接口

介绍软件进一步维护的方法,描述对现有系统进行改进和维护的相关模块,介绍维护的软件接口。

9、总结

通过本次实践使我MFC编程有了一定的认识,提高了我对于C++面向对象程序设计功能优点的认识度。由于是第一次接触到MFC编程,所以有很多概念不是很明白,在进行实践活动的过程中,我又自学了一些关于MFC编程的书籍,了解了进行MFC编程的一些深层次的问题,比如,对于MFC主要是一个消息驱动编程思想的认识。在自学的过程中,进一步提高了我寻找信息,和筛选信息的能力。也同时提高了我的自学能力。但是在本次实践活动中,由于主观和客观的各种因素,我没能完成人机对战和网络对战的编写,自己感觉很是遗憾。不过,我还是感到庆幸的是,通过这次实践活动,把我带进MFC编程这个美丽的,充满魅力的殿堂。师傅领进门,修行在个人。在这次实践活动结束以后,就完全是修行在个人了,我感谢给我指明方向,带我进入这个编程的殿堂的人,我也将在这个神奇,美丽的殿堂里慢慢学习。事在人为。

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: