MFC编写的五子棋源程序,包含详细的设计文档,软件工程课程设计课要求完成的大作业...

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

项目名称

课程实践报告书

制订人:

 号:

2005年 5月 14日


文档变更历史记录

序号变更日期变更人员变更内容详情描述版本
12001/11/1张三创建1.0
22001/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编程这个美丽的,充满魅力的殿堂。师傅领进门,修行在个人。在这次实践活动结束以后,就完全是修行在个人了,我感谢给我指明方向,带我进入这个编程的殿堂的人,我也将在这个神奇,美丽的殿堂里慢慢学习。事在人为。

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值