1、中北大学本科毕业设计说明书 第 1 页 共 30 页 1 引言 1.1 五子棋介绍 五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連珠”,英译为“ Renju”,英文称之为“ Gobang”或“ FIR”( Five in a Row 的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。 五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的 棋文化源渊流长,具有东
2、方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。 1.2 开发背景 当前网络上流传的五子棋游戏功能并不尽善尽美,其中最主要的问题就是人机对战和网络对战不能够一起实现,所以我决定开发 1一个既能够人机对战,又能够进行网络对战的五子棋系统。 1.3 开发环境及运行环境 1.3.1 开发环境 Intel Pentium 4 2.0GHz, 512M 内存, 80G 硬盘 Microsoft Windows 2000 Professional Microsoft Visual C+ 6.0 Microsoft Developer Network for
3、 Visual Studio.NET 2003 Visual Assist X 10.1.1301.0 1.3.2 运行环境 Intel Pentium 2及以上处理器, 32M 以上内存, 4G以上硬盘 Microsoft Windows 9X/NT 操作系统 800*600 或以上的屏幕分辨率 中北大学本科毕业设计说明书 第 2 页 共 30 页 2 软件架构 软件的总体架构如图 2.1: 图 2.1 软件架构 考虑到整个的下棋过程(无论对方是电脑抑或其他网络玩家)可以分为:己方落子、等待对方落子、对方落子、设置己方棋盘数据这一系列过程,因此一人游戏类、二人游戏类和棋盘类之间的关系参考了
4、AbstractFactory(抽象工厂)模式,以实现对两个不同模块进行一般化的控制。 2 2.1 棋盘类 整个架构的核心部分,类名为 CTable。封装了棋盘的各种可能用到的功能 3,如保存棋盘数据、初始化、判断胜负等。用户操作主界面,主界面与 CTable进行交互来完成对游戏的操作。 2.2 游戏模 式类 用来管理人机对弈 /网络对弈两种游戏模式,类名为 CGame。 CGame 是一个抽一人游戏类 二人游戏类 棋盘类 主界面 用户 游戏类指针 中北大学本科毕业设计说明书 第 3 页 共 30 页 象类,经由它派生出一人游戏类 COneGame 和网络游戏类 CTwoGame,如 图 2.
5、2: 图 2.2 CGame 类派生关系 这样, CTable 类就可以通过一个 CGame 类的指针 4,在游戏初始化的时候根据具体游戏模式的要求实例化 COneGame 或 CTwoGame 类的对象;然后利用多态性 5,使用 CGame类提供的公有接口就可以完成不同游戏模式下的 不同功能了。 抽象类 CGame COneGame CTwoGame 中北大学本科毕业设计说明书 第 4 页 共 30 页 3 棋盘类 CTable 3.1 主要成员变量说明 3.1.1 网络连接标志 m_bConnected 用来表示当前网络连接的情况,在网络对弈游戏模式下客户端连接服务器的时候用来判断是否连接
6、成功;事实上,它也是区分当前游戏模式的唯一标志。 3.1.2 棋盘等待标志 m_bWait与 m_bOldWait 由于在玩家落子后需要等待对方落子, m_bWait 标志就用来标识棋盘的等待状态。当 m_bWait为 TRUE 时,是不允许玩家落子的。 在网络对弈模式下,玩家之 间需要互相发送诸如悔棋、和棋这一类的请求消息,在发送请求后等待对方回应时,也是不允许落子的,所以需要将 m_bWait 标志置为 TRUE。在收到对方回应后,需要恢复原有的棋盘等待状态,所以需要另外一个变量在发送请求之前保存棋盘的等待状态做恢复之用,也就是 m_bOldWait。 等待标志的设置,由成员函数 SetW
7、ait和 RestoreWait 完成。 3.1.3 网络套接字 m_sock和 m_conn 在网络对弈游戏模式下,需要用到这两个套接字对象。其中 m_sock 对象用于做服务器时的监听之用, m_conn 用于网 络连接的传输。 3.1.4 棋盘数据 m_data 这是一个 15*15 的二位数组,用来保存当前棋盘的落子数据。其中对于每个成员来说, 0 表示落黑子, 1 表示落白子, -1表示无子。 3.1.5 游戏模式指针 m_pGame 这个 CGame类的对象指针是 CTable 类的核心内容。它所指向的对象实体决中北大学本科毕业设计说明书 第 5 页 共 30 页 定了 CTabl
8、e 在执行一件事情时候的不同行为,具体的内容请参见“游戏模式”一节。 3.2 主要成员函数说明 3.2.1 套接字的回调处理 Accept、 Connect、 Receive 本程序的套接字派生自 MFC 的 CAsyncSocket 类 6, CTable 的这三个成员函数就分别提供了对套接字 7回调事件 OnAccept、 OnConnect、 OnReceive 的实际处理,其中尤以 Receive 成员函数重要,它之中包含了对所有网络消息(参见“消息机制”一节)的分发处理。 3.2.2 清空棋盘 Clear 在每一局游戏开始的时候都需要调用这个函数将棋盘清空,也就是棋盘的初始化工作。在
9、这个函数中,主要发生了这么几件事情: 将 m_data中每一个落子位都置为无子状态( -1)。 按照传入的参数设置棋盘等待标志 m_bWait,以供先、后手的不同情况之用。 使用 delete将 m_pGame 指针所指向的原有游戏模式对象从堆上删除。 3.2.3 绘制棋子 Draw 这无疑是很重要的一个函数,它根据参数给定的坐标和颜色绘制棋子。绘制的详细过程如下: 将给定的棋盘坐标换算为绘图的像素坐标。 根据坐标绘制棋子位图。 如果先前曾下过棋子,则利用 R2_NOTXORPEN 将上一个绘制棋子上的最后落子指示矩形擦除。 在刚绘制完成的棋子四周绘制最后落子指示矩形。 中北大学本科毕业设计说
10、明书 第 6 页 共 30 页 3.2.4 左键消息 OnLButtonUp 作为棋盘唯一响应的左键消息,也需要做 不少的工作: 如果棋盘等待标志 m_bWait 为 TRUE,则直接发出警告声音并返回,即禁止落子。 如果点击时的鼠标坐标在合法坐标 (0, 0) (14, 14)之外,亦禁止落子。 如果走的步数大于 1步,方才允许悔棋。 进行胜利判断,如胜利则修改 UI 状态并增加胜利数的统计。 如未胜利,则向对方发送已经落子的消息。 落子完毕,将 m_bWait标志置为 TRUE,开始等待对方回应。 3.2.5 绘制棋盘 OnPaint 每当 WM_PAINT 消息触发时,都需要对棋盘进行重
11、绘。 OnPaint 作为响应绘制消息的消息处理函数 使用了双缓冲技术,减少了多次绘图可能导致的图像闪烁问题。这个函数主要完成了以下工作: 装载棋盘位图并进行绘制。 根据棋盘数据绘制棋子。 绘制最后落子指示矩形。 3.2.6 对方落子完毕 Over 在对方落子之后,仍然需要做一些判断工作,这些工作与 OnLButtonUp 中的类似,在此不再赘述。 3.2.7 设置游戏模式 SetGameMode 这个函数通过传入的游戏模式参数对 m_pGame 指针进行了初始化,代码如下: void CTable:SetGameMode( int nGameMode ) if ( 1 = nGameMode
12、 ) 中北大学本科毕业设计说明书 第 7 页 共 30 页 m_pGame = new COneGame( this ); else m_pGame = new CTwoGame( this ); m_pGame-Init(); 这之后,就可以利用 OO 的继承和多态特点 8来使 m_pGame 指针使用相同的调用来完成不同的工作了,事实上, COneGame:Init 和 CTwoGame:Init 都是不同的。 3.2.8 胜负的判断 Win 这是游戏中一个极其重要 的算法,用来判断当前棋盘的形势是哪一方获胜。其详细内容请参见“主要算法”一节。 中北大学本科毕业设计说明书 第 8 页 共
13、30 页 4 游戏模式类 CGame 这个类负责对游戏模式进行管理,以及在不同的游戏模式下对不同的用户行为进行不同的响应。由于并不需要 CGame 本身进行响应,所以将其设计为了一个纯虚类 9,它的定义如下: class CGame protected: CTable *m_pTable; public: / 落子步骤 list m_StepList; public: / 构造函数 CGame( CTable *pTable ) : m_pTable( pTable ) / 析构函数 virtual CGame(); / 初始化工作,不同的游戏方式初始化也不一样 virtual void In
14、it() = 0; / 处理胜利后的情况, CTwoGame需要改写此函数完成善后工作 virtual void Win( const STEP / 发送己方落子 virtual void SendStep( const STEP / 接收对方消息 virtual void ReceiveMsg( MSGSTRUCT *pMsg ) = 0; / 发送悔棋请求 中北大学本科毕业设计说明书 第 9 页 共 30 页 virtual void Back() = 0; ; 4.1 主要成员变量说明 4.1.1 棋盘指针 m_pTable 由于在游戏中需要对棋盘以及棋盘的父窗口 主对话框进行操作及 U
15、I 状态设置,故为 CGame 类设置了这个成员。当 对主对话框进行操作时,可以使用m_pTable-GetParent()得到它的窗口指针 。 4.1.2 落子步骤 m_StepList 一个好的棋类程序必须要考虑到的功能就是它的悔棋功能,所以需要为游戏类设置一个落子步骤的列表。由于人机对弈和网络对弈中都需要这个功能,故将这个成员直接设置到基类 CGame 中。另外,考虑到使用的简便性,这个成员使用了 C+标准模板库 10( Standard Template Library, STL)中的 std:list,而不是 MFC的 CList。 4.2 主要成员函数说明 4.2.1 悔棋操作 B
16、ack 在不同的游戏模式下,悔棋的行为是不一样的。 人机对弈模式下,计算机是完全允许玩家悔棋的,但是出于对程序负荷的考虑(此原因请参见“几点补充说明”一节),只允许玩家悔当前的两步棋(计算机一步,玩家一步)。 双人网络对弈模式下,悔棋的过程为:首先由玩家向对方发送悔棋请求(悔棋消息),然后由对方决定是否允许玩家悔棋,在玩家得到对方的响应消息(允许或者拒绝)之后,才进行悔棋与否的操作。 4.2.2 初始化操作 Init 中北大学本科毕业设计说明书 第 10 页 共 30 页 对于不同的游戏模式而言,也就有不同的初始化方式。对于人机对弈 模式而言,初始化操作包括以下几个步骤: 设置网络连接状态 m
17、_bConnected为 FALSE。 设置主界面计算机玩家的姓名。 初始化所有的获胜组合。 如果是计算机先走,则占据天元(棋盘正中央)的位置。 网络对弈的初始化工作暂为空,以供以后扩展之用。 4.2.3 接收来自对方的消息 ReceiveMsg 这个成员函数由 CTable 棋盘类的 Receive 成员函数调用,用于接收来自对方的消息。对于人机对弈游戏模式来说,所能接收到的就仅仅是本地模拟的落子消息 MSG_PUTSTEP;对于网络对弈游戏模式来说,这个成 员函数则负责从套接字读取对方发过来的数据,然后将这些数据解释为自定义的消息结构,并回到CTable:Receive来进行处理。 4.2.4 发送落子消息 SendStep 在玩家落子结束后,要向对方发送自己落子的消息。对于不同的游戏模式,发送的目标也不同: 对于人机对弈游戏模式,将直接把落子的信息(坐标、颜色)发送给COneGame类相应的计算函数。 对于网络对弈游戏模式,将把落子消息发送给套接字,并由套接字转发给对方。 4.2.5 胜利后的处理 Win 这个成员函数主要针对 CTwoGame 网络对弈模 式。在玩家赢得棋局后,这个函数仍然会调用 SendStep 将玩家所下的制胜落子步骤发送给对方玩家,然后对