网络五子棋设计与实现(3)

2018-12-22 21:59

m_pGame->Init(); }

这之后,就可以利用OO的继承和多态性特点来使m_pGame指针使用相同的调用来完成不同的工作了,事实上,COneGame::Init和CTwoGame::Init都是不同的。 5.2.8 胜负的判断——Win

这是游戏中一个极其重要的算法,用来判断当前棋盘的形势是哪一方获胜。其详细内容请参见“主要算法”一节。

6 游戏模式类——CGame

此类负责对游戏模式进行管理,以及在不同的游戏模式下对不同的用户行为进行不同的响应。由于并不需要CGame本身进行响应,所以将其设计为了一个纯虚类,它的定义如下: class CGame { protected:

CTable *m_pTable; public:

list< STEP > m_StepList; // 落子步骤 public:

CGame( CTable *pTable ) : m_pTable( pTable ) {}// 构造函数 virtual ~CGame();// 析构函数 virtual void Init() = 0; // 初始化工作

// 处理胜利后的情况,CTwoGame需要改写此函数完成善后工作

virtual void Win( const STEP& stepSend );

// 发送己方落子

virtual void SendStep( const STEP& stepSend ) = 0;

virtual void ReceiveMsg( MSGSTRUCT *pMsg ) = 0; // 接收对方消息 virtual void Back() = 0; // 发送悔棋请求 };

6.1 主要成员变量说明

6.1.1 棋盘指针——m_pTable

由于在游戏中需要对棋盘以及棋盘的父窗口——主对话框进行操作及UI状态设

- 8 -

置,故为CGame类设置了这个成员。当对主对话框进行操作时,可以使用m_pTable->GetParent()得到它的窗口指针。 6.1.2 落子步骤——m_StepList

好的棋类程序必须要考虑悔棋功能,所以需要为游戏类设置一个落子步骤列表。而人机对弈和网络对弈中都需要这个功能,故将这个成员直接设置到基类CGame中。另外,考虑到使用的简便性,这个成员使用了C++标准模板库(Standard Template Library,STL)中的std::list,而不是MFC的CList。

6.2 主要成员函数说明

6.2.1 悔棋操作——Back

在不同的游戏模式下,悔棋的行为是不一样的。

(1) 人机对弈模式下,计算机是完全允许玩家悔棋的,但是出于对程序负荷的考虑,只允许玩家悔当前的两步棋(计算机一步,玩家一步)。

(2) 双人网络对弈模式下,悔棋的过程为:首先由玩家向对方发送悔棋请求(悔棋消息),然后由对方决定是否允许玩家悔棋,在玩家得到对方的响应消息(允许或者拒绝)之后,才进行悔棋与否的操作。 6.2.2 初始化操作——Init

对于不同的游戏模式而言,也就有不同的初始化方式。对于人机对弈模式而言,初始化操作包括以下几个步骤:

(1) 设置网络连接状态m_bConnected为FALSE。 (2) 设置主界面计算机玩家的姓名。 (3) 初始化所有的获胜组合。

(4) 如果是计算机先走,则占据天元(棋盘正中央)的位置。 网络对弈的初始化工作暂为空,以供以后扩展之用。 6.2.3 接收来自对方的消息——ReceiveMsg

这个成员函数由CTable棋盘类的Receive成员函数调用,用于接收来自对方的消息。在人机对弈游戏模式下,所能接收到的是本地模拟的落子消息MSG_PUTSTEP;在网络对弈游戏模式下,这个成员函数则负责从套接字读取对方发过来的数据,然后将这些数据解释为自定义的消息结构,并回到CTable::Receive来进行处理。 6.2.4 发送落子消息——SendStep

在玩家落子结束后,要向对方发送自己落子的消息。对于不同的游戏模式, 发送的目标不同:

- 9 -

(1) 在人机对弈游戏模式,直接把落子的信息(坐标、颜色)发送给COneGame类相应的计算函数。

(2) 在网络对弈游戏模式,则把落子消息发送给套接字,并由套接字转发给对方。

6.2.5 胜利后的处理——Win

这个成员函数主要针对CTwoGame网络对弈模式。在玩家赢得棋局后,这个函数游戏端经由CTable::Win来判定双方胜败。

7 消息机制

Windows系统拥有自己的消息机制,在不同事件发生的时候,系统可以提供不同的响应方式。五子棋程序模仿Windows系统实现了自己的消息机制,主要为网络对弈服务,以响应不同的网络消息。

7.1 消息机制的架构

当继承CAsyncSocket的套接字类CFiveSocket收到消息时,会触发CFiveSocket::OnReceive事件,在这个事件中调用CTable::Receive,CTable::Receive开始按照自定义的消息格式接收套接字发送的数据,并对不同的消息类型进行分发处理。

当CTable获得了来自网络的消息之后,就可以使用一个switch结构来进行消息的分发了。消息机制过程如图3:

CFiveSocket 网络数据 CFiveSocket::OnReceive 调用 CTable::Receive 分发处理 CFiveSocket::Receive - 10 -

图3 自定义的消息机制

Figure 3 defined mechanism for information

7.2 各种消息说明

网络间传递的消息,都遵循以下一个结构体的形式: typedef struct _tagMsgStruct { // 摘自Messages.h UINT uMsg; // 消息ID int x; // 落子信息 int y; int color;

TCHAR szMsg[128]; // 消息内容

} MSGSTRUCT;

随着uMsg表示消息ID,x 、y表示落子的坐标 ,color表示落子的颜色 ,szMsg随着uMsg的不同而有不同的含义。 7.2.1 落子消息——MSG_PUTSTEP

表明对方落下了一个棋子,其中x、y和color成员有效,szMsg成员无效。在人机对弈游戏模式下,亦会模拟发送此消息以达到程序模块一般化的效果。 7.2.2 聊天消息——MSG_CHAT

表明对方发送了一条聊天信息,szMsg表示对方的信息,其余成员无效。接到这个信息后,会将对方聊天的内容显示在主对话框的聊天记录窗口内。如图4:

- 11 -

图4 聊天窗口 Figure 4 chat window

7.2.3 悔棋消息——MSG_BACK

表明对方请求悔棋,除uMsg成员外其余成员皆无效。接到这个消息后,会弹出MessageBox询问是否接受对方的请求(如图5所示),并根据玩家的选择回返MSG_AGREEBACK或MSG_REFUSEBACK消息。另外,在发送这个消息之后,主界面上的某些元素将不再响应用户的操作。

图5 请求悔棋 Figure 5 calculate request

7.2.4 同意悔棋消息——MSG_AGREEBACK

表明对方接受了玩家的悔棋请求,除uMsg成员外其余成员皆无效。接到这个消息后,将进行正常的悔棋操作。

7.2.5 拒绝悔棋消息——MSG_REFUSEBACK

表明对方拒绝了玩家的悔棋请求(如图6所示),除uMsg成员外其余成员皆无效。接到这个消息后,整个界面将恢复发送悔棋请求前的状态。

- 12 -


网络五子棋设计与实现(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:市场营销第3阶段测试题答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: