局域网对战五子棋游戏设计.doc
目 录一、需求分析- 2 -1.1 开发背景- 2 -1.2 项目目标- 2 -1.3 运行环境- 2 -1.4 游戏说明- 3 -1.5 项目任务书- 3 -二、总体设计- 4 -2.1 总体方案- 4 -2.2 详细设计- 6 -三、工程进度- 31 -3.1 前期准备部分(第1-3天)- 31 -3.2中期实现功能部分(第4-7天)- 31 -3.3后期总结完善部分(第8-10天)- 31 -四、测试报告- 32 -4.1 测试棋谱- 32 -4.2 网络连接测试- 32 -4.4游戏互动测试- 33 -4.5总体测试- 34 -五、 个人小结- 34 -一、需求分析 1.1 开发背景五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“连珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。 五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。1.2 项目目标 我们将主要通过VC+语言,运用面向对象的程序设计方法,开发此款五子棋游戏。力争使程序短小精悍,简洁明了;游戏界面优美,容易操作;功能丰富,趣味性强。现在将我们对项目期望实现的目标一一介绍:(1) 能够实现五子棋游戏中的全部规则 能够对连五的胜负进行判断,并给出提示 能够对黑方禁手进行判断,并能够在落子后进行直接判负的提示。(2) 能够支持设置网络端口 玩家可以自行设定连接的服务器IP地址。通信端口默认使用10000 支持两个玩家进行练级网络对弈模式。 支持和棋操作。 1.3 运行环境 本游戏短小精悍,而且对电脑配置的要求均不高,目前几乎所有的PC机均可运行该游戏。但是为了能让大家更好地体验该款游戏,我们给出如下的最低配置: 最低配置:CPU1GHz 内存 32M 硬盘 4G Windows 95 Microsoft Visual C+ 6.0 同时结合我们开发该游戏的环境,我们强烈推荐用户使用如下的配置: 最佳配置:CPU2GHz及以上 内存256M及以上 硬盘80G及以上 Windows XP及以上 Microsoft Visual C+ 6.01.4 游戏说明(1) 游戏流程:启动游戏后,显示主菜单。里面包括开始游戏、和棋、游戏帮助、退出。 (2) 游戏规则:1、黑先白后,从天元开始落子。然后执白棋的一方在黑棋周围的交叉点上落子,白第二着棋应布在自己河界的一侧。此后,执黑方在以天元为中心的25个交叉点的范围内布盘面的第三着棋。2、最先在横向,竖向,斜向形成连续的相同色五个棋子的一方为胜。3、黑棋禁手判负,白棋无禁手。黑棋禁手包括“三三”,“四四”,“长连”。黑方只能“四三”胜。所谓禁手,是指黑方一子落下同时形成两个或两个以上的活三,冲四及长连禁手。长连禁手是指黑方形成六个或六个以上的连续棋子。4、双方均不能形成五连为和棋。5、对局中拔子,中途退场均判为负。6、五连与禁手同时形成,先五为胜。因黑方已形成五连,故禁手失效,黑方胜。7、黑方禁手形成时,白方应立即指出禁手点,黑方即负。若白方继续应子,则黑方禁手不成立。8、高段位职业比赛的特殊规定:“三手可交换”:黑下完第手,执白者可提出交换。即执白方变为执黑方。“五手两打法”:执黑下第五手时,必须下两手棋,执白者从这两手棋中任选一步。本文所论述的联机五子棋系统就是依照这种方式进行的。1.5 项目任务书(1) 班级:测控1001(2) 组长:莫旭鹏(3) 成员:崔州靖 苗志涛(4) 项目名称: 五子棋(5) 项目背景:五子棋是起源于中国古代的传统黑白棋种之一。五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”。 (6) 项目分工:崔州靖:负责完成项目需求分析,并提供给组员。 莫旭鹏:负责项目的总体设计及详细设计。将五子棋初期程序给出。 苗志涛:负责项目的后期测试与调整,并完成测试报告。 (7) 项目进度:1-3天:前期准备,各类资料收集,流程图,算法等同时完成。 4-7天:实现基本功能和附加功能。 8-10天:最后测试,最后优化。(各类文档的设计与编写穿插于始终) 二、总体设计2.1 总体方案网络五子棋(1) 系统功能架构:输入服务器IP地址选择先手或者后手游戏版本号查询 退出游戏游戏规则判断网络交互和棋(2) 处理流程整个五子棋的处理流程如图所示:选中菜单中的“开始”项选择网络类型,为客户机设置主机IP地址,进行网络连接 游戏准备主机为黑色,客户机为白色由黑方开始落子 根据规则判断 开始游戏 黑方连五 或禁手传送数据到主机,等待由白方开始落子根据判断规则 白方连五 传送数据到主机,等待游戏结束,通知结果 游戏结束 (3) 类结构设计游戏由五个类组成,如图所示:五子棋游戏游戏规则类网络协议类网络通信类棋盘窗口类客户端对话框类 游戏规则类:主要负责各种类的调用及游戏规则的实现。 棋盘窗口类:主要负责棋盘和棋子等的更新和显示。 设置对话框类:主要负责参数的设置与连接。 网络通信类:主要负责游戏的网络通信。 网络协议类:主要负责游戏网络通信协议的实现。(4) 出错处理设计 当游戏中的一方出现错误。游戏的错误处理类会采用弹出对话框的方式提示用户出错信息。2.2 详细设计详细设计就是使设计和实现前面的各种类结构本小组是按:网络通信协议类设计与实现-交互界面的设计与实现-棋盘窗口类的设计与实现-网络交互的设计与实现-游戏规则的设计与实现-游戏中主对话框类的设计与实现的顺序进行设计和完成编码的1、 网络通信协议的设计与实现 游戏中棋子在棋盘中的坐标,及棋子的位置。 游戏中的控制信息。 其他扩展信息。 为能适应3种不同类的信息的传输,所以在游戏的网络传输协议中,必须加入一个网络协议包结构。如图:数 据 长 度信 息 类 型数 据按照该格式可以设计出各种数据类型的详细结构。2、 交互界面的设计与实现(1) 控制菜单的设计 在本小组的设计的五子棋中,有3中操作命令需要使用菜单来支持: A、新游戏操作,当用户进行主界面后,需要这个菜单项来开始新的游戏。开始新游戏之前需要对网络进行设置。 B、和棋操作,在游戏中由一方提出提前结束游戏。相当于认输并重新开始新一轮游戏、 C、退出游戏操作,当前用户不需要再玩游戏时,直接退出整个游戏界面。(2) 控制菜单的实现 为实现菜单,就需要在五子棋项目的资源中加入一个菜单栏(IDR_MAIN_MENU),并且要设置相应的ID资源号。(3) 网络设置对话框的设计 在游戏开始时,需要对网络进行设置,其包含的内容如下: A、可以选择当前用户是主机,还是客户机。如果是主机则执黑子,如果是客户机则执白子。B、当用户选择为主机时,IP地址默认为:“127.0.0.1”,端口号由用户填写。C、当用户为客户机时,则需要在设置连接到主机的IP地址及端口号。D、如果上面已经设置过,则从新开始游戏时,把上一次设置的IP地址和端口号显示出来。3、 棋盘窗口类的设计与实现 (1)设计 本组设计的五子棋需支持如下几个功能: 能够显示棋盘和棋子图片。 能够接受用户鼠标输入,并把相应的坐标转换成相应的行列数据填充到棋子数组中。 能够处理来在网络通信的各种数据。 能够调用规则类来对象判断胜负。 能够支持清空游戏棋盘上的棋子的功能。(2) 棋盘类的实现 有了支持的功能列表,就需要声明一个棋盘类,其代码如下:#ifndef _BOARD_H_#define _BOARD_H_#include "stdafx.h"class CBoard:public CWndprivate: CImageList m_iml; / 棋子图像 int m_color; / 玩家颜色 BOOL m_bWait; / 等待标志BOOL m_bOldWait;/原来的等待状态 public:CBoard(); virtual CBoard();void RestoreWait(); void Clear( BOOL bWait ); void SetColor(int color); int GetColor() const; void SetWait( BOOL bWait ); void SetData( int x, int y, int color ); void DrawGame();void Draw(int x, int y, int color);void Receive();void Over(int x, int y);protected: afx_msg void OnPaint(); afx_msg void OnLButtonUp( UINT nFlags, CPoint point ); DECLARE_MESSAGE_MAP();#endif(3) 棋盘类函数的实现以上是声明了类的结构和成员,之后要根据这些声明,对这个类进行基函数实现,其代码如下:#include "board.h"#include "Resource.h"#include "ConnectData.h"#include "Rule.h"#include "FiveChessDlg.h"#define MAX_LEN 256/*定义最大长度*/ 构造函数,初始化棋盘数据以及图像数据/CBoard:CBoard() / 初始化图像列表 m_iml.Create( 24, 24, ILC_COLOR24 | ILC_MASK, 0, 2 ); / 载入黑、白棋子掩码位图 CBitmap bmpBlack, bmpWhite; bmpBlack.LoadBitmap( IDB_BMP_BLACK ); m_iml.Add( &bmpBlack, 0xff00ff ); bmpWhite.LoadBitmap( IDB_BMP_WHITE ); m_iml.Add( &bmpWhite, 0xff00ff );/ 析构函数/CBoard:CBoard()/ 消息映射表BEGIN_MESSAGE_MAP( CBoard, CWnd )/AFX_MSG_MAP(CBoard) ON_WM_PAINT() ON_WM_LBUTTONUP()/AFX_MSG_MAPEND_MESSAGE_MAP()/ 处理WM_PAINT消息/void CBoard:OnPaint() CPaintDC dc( this ); CDC MemDC; MemDC.CreateCompatibleDC( &dc ); / 装载棋盘 CBitmap bmp; CPen pen; bmp.LoadBitmap( IDB_BMP_QP ); pen.CreatePen( PS_SOLID, 1, 0xff ); MemDC.SelectObject( &bmp ); MemDC.SelectObject( &pen ); MemDC.SetROP2( R2_NOTXORPEN ); / 根据棋盘数据绘制棋子 int x, y; POINT pt; for ( y = 0; y < 15; y+ ) for ( x = 0; x < 15; x+ ) if ( -1 != m_dataxy ) pt.x = 12 + 25 * x; pt.y = 84 + 25 * y; m_iml.Draw( &MemDC, m_dataxy, pt, ILD_TRANSPARENT ); / 完成绘制 dc.BitBlt( 0, 0, 395, 472, &MemDC,0, 0, SRCCOPY );/ 处理左键弹起消息,为玩家落子之用/void CBoard:OnLButtonUp( UINT nFlags, CPoint point )MSGSTRUCT msg;CRule rule;CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();BYTE bufMAX_LEN = 0; if ( m_bWait) MessageBeep( MB_OK ); return; if(pDlg->m_bIsConnect)int x, y;x = ( point.x - 12 ) / 25;y = ( point.y - 84 ) / 25;/ 如果在(0, 0)(14, 14)范围内,且该坐标没有落子,/ 则落子于此,否则发声警告并退出过程if ( x < 0 | x > 14 | y < 0 | y > 14 | m_dataxy != -1 )MessageBeep( MB_OK );return;else/ 如果位置合法,则落子SetData( x, y, m_color );msg.color = m_color;msg.x = x;msg.y = y;/ 开始等待m_bWait = TRUE;msg.msgType = MSG_PUTSTEP;pDlg->Send(&msg);if(rule.Win(m_color, msg.x, msg.y) = _WIN)/ 胜利pDlg->MessageBox( _T("恭喜,您获得了胜利!"), _T("胜利"), MB_ICONINFORMATION );pDlg->SetMenuState(TRUE);else if(rule.Win(m_color, msg.x, msg.y) = _LOST)/出现禁手pDlg->MessageBox( _T("执黑禁手, 您输了!"), _T("失败"), MB_ICONINFORMATION );pDlg->SetMenuState(TRUE);/ 清空棋盘/void CBoard:Clear( BOOL bWait ) int x, y; for ( y = 0; y < 15; y+ ) for ( x = 0; x < 15; x+ ) m_dataxy = -1; / 设置等待标志 m_bWait = bWait; Invalidate();/ 设置玩家颜色/void CBoard:SetColor(int color)m_color = color;/ 获取玩家颜色/int CBoard:GetColor() constreturn m_color;/ 设置等待标志/void CBoard:SetWait( BOOL bWait )m_bOldWait = m_bWait;m_bWait = bWait;/ 设置棋盘数据,并绘制棋子/void CBoard:SetData( int x, int y, int color ) m_dataxy = color; Draw( x, y, color );/ 在指定棋盘坐标处绘制指定颜色的棋子/void CBoard:Draw(int x, int y, int color) POINT pt; pt.x = 12 + 25 * x; pt.y = 84 + 25 * y; CDC *pDC = GetDC(); CPen pen; pen.CreatePen( PS_SOLID, 1, 0xff ); pDC->SelectObject( &pen ); pDC->SetROP2( R2_NOTXORPEN ); m_iml.Draw( pDC, color, pt, ILD_TRANSPARENT ); ReleaseDC( pDC );/ 接收来自对方的数据/void CBoard:Receive()CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();MSGSTRUCT msg;if(pDlg->m_sock.Receive(LPVOID)&msg, sizeof(MSGSTRUCT) = SOCKET_ERROR)AfxGetMainWnd()->MessageBox( _T("接收数据时发生错误,请检查您的网络连接。"), _T("错误"), MB_ICONSTOP );return;switch(msg.msgType)case MSG_PUTSTEP:SetData( msg.x, msg.y, msg.color );Over(msg.x, msg.y);break;case MSG_DRAW:if ( IDYES = GetParent()->MessageBox( _T("对方请求和棋,接受这个请求吗?"),_T("和棋"), MB_ICONQUESTION | MB_YESNO ) )/ 发送允许和棋消息MSGSTRUCT msg;msg.msgType = MSG_AGREE_DRAW;pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );SetWait( TRUE );/ 使“重玩”菜单生效pDlg->SetMenuState(TRUE);else/ 发送拒绝和棋消息MSGSTRUCT msg;msg.msgType = MSG_REFUSE_DRAW;pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );break;case MSG_AGREE_DRAW:pDlg->MessageBox( _T("看来真是棋逢对手,对方接受了您的和棋请求。"), _T("和棋"), MB_ICONINFORMATION );/ 和棋后,使“重玩”菜单生效pDlg->SetMenuState(TRUE);break;case MSG_REFUSE_DRAW:pDlg->MessageBox( _T("看来对方很有信心取得胜利,所以拒绝了您的和棋请求。"),_T("和棋"), MB_ICONINFORMATION );RestoreWait();pDlg->SetMenuState(FALSE);break;case MSG_EXTERN:break;default:break;/ 和棋操作/void CBoard:DrawGame()CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd(); / 设置等待标志 SetWait( TRUE ); MSGSTRUCT msg; msg.msgType = MSG_DRAW; pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );/ 处理对方落子后的工作/void CBoard:Over(int x, int y)CRule rule;CFiveChessDlg *pDlg = (CFiveChessDlg *)GetParent();/ 判断对方是否胜利 if ( rule.Win( 1 - m_color, x, y ) = _WIN) pDlg->MessageBox( _T("您输了,不过不要灰心,失败乃成功之母哦!"), _T("失败"), MB_ICONINFORMATION ); / 如果是网络对战,则生效“重玩” if ( pDlg->m_bIsConnect ) pDlg->SetMenuState(TRUE); return; /判断对方是否出现禁手else if(rule.Win(1 - m_color, x, y) = _LOST)pDlg->MessageBox( _T("恭喜您, 对方出现禁手输了!"), _T("胜利"), MB_ICONINFORMATION );/ 如果是网络对战,则生效“重玩”if ( pDlg->m_bIsConnect )pDlg->SetMenuState(TRUE);return;m_bWait = FALSE;/ 重新设置先前的等待标志/void CBoard:RestoreWait() SetWait( m_bOldWait );(4) 注册棋盘窗口类 另外,要是用这个棋盘类,还必须在应用程序类的注册棋盘窗口类,其代码如下:/ 注册棋盘窗口类 WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wc.hCursor = LoadCursor( IDC_ARROW ); wc.hIcon = NULL; wc.hInstance = AfxGetInstanceHandle(); wc.lpfnWndProc = :DefWindowProc; wc.lpszClassName = _T("ChessBoard"); wc.lpszMenuName = NULL; wc.style = 0; AfxRegisterClass( &wc );CFiveChessDlg dlg;m_pMainWnd = &dlg;int nResponse = dlg.DoModal();if (nResponse = IDOK)/ TODO: Place code here to handle when the dialog is/ dismissed with OKelse if (nResponse = IDCANCEL)/ TODO: Place code here to handle when the dialog is/ dismissed with Cancel/ Since the dialog has been closed, return FALSE so that we exit the/ application, rather than start the application's message pump.return FALSE;4、 网络交互界面的设计与实现 根据之前需求分析以及网络通信协议中所要求功能,可以进行编码,应首先实现CConnet类的声明,之后再根据需要实现各种操作响应函数。 CConnect类的声明如以下代码:#ifndef _CONNECT_H_#define _CONNECT_H_#include <afxsock.h>class CConnect: public CAsyncSocket public:CConnect();/构造函数virtual CConnect();/析构函数/ Implementationprotected:virtual void OnAccept( int nErrorCode );virtual void OnConnect( int nErrorCode );virtual void OnReceive( int nErrorCode );virtual void OnClose( int nErrorCode );#endifCConnect的实现即以下代码:#include "Connect.h"#include "FiveChessDlg.h"#include "Board.h"CConnect:CConnect()CConnect:CConnect()/ CFiveSocket member functionsvoid CConnect:OnAccept( int nErrorCode )CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();pDlg->Accept();pDlg->SetMenuState(FALSE);void CConnect:OnClose( int nErrorCode )CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();pDlg->MessageBox( _T("对方已经离开游戏,改日再较量不迟。"), _T("五子棋"), MB_ICONINFORMATION);pDlg->SetMenuState(TRUE);pDlg->m_board.SetWait(TRUE);pDl