千万建筑资料下载 →
五子棋游戏(网络版)的设计与开发
摘要
网络游戏的出现代表了一种全新娱乐方式的诞生。目前网络游戏正以其独特的魅力吸引着众多的玩家。随着游戏产业的蓬勃发展,将需要越来越多的人加入到游戏开发中来。
本毕业设计所完成的五子棋游戏(网络版)是在WindowsXP下使用MicrosoftVisualC++6.0开发的C/S系统,可以实现网络间的双人对战,并且可以提供多媒体播放功能。系统的多媒体播放功能可以播放MP3、WMA等主流格式的音乐。
本论文从基本网络套节字开始入手,介绍了一些本系统相关的理论知识,随后详细介绍了五子棋游戏(网络版)的开发过程。包括服务器端、客户端的socket编程,五子棋服务器和客户端通信的实现,五子棋判断算法的实现,主界面视图,多媒体播放以及定时器等附加功能的实现。最后对系统进行测试并对所做工作进行总结。
关键词:网络游戏;五子棋;VC;WinSocket;MCI
TheDesignandDevelopmentoftheon-lineBlack&WhiteGameAbstract
On-linegamesbringtoanewformofentertainment.Untilnow,on-linegamesischarmingmoreandmoreplayers.Asthedevelopmentofgameindustry,therewillbemoreandmoredevelopersjoininthegamedevelopmentteam.
Theon-lineBlack&WhitegamewasdevelopedbyMicrosoftVisualC++6.0onWindowsXPplatform.Inthisgame,twopeoplecanplaythegameonline,andthegamealsoprovidesmultimediaplayerfunction.
Thethesisstartwithintroductionofnetworksocketprogramming,thedevelopmentprocessingoftheon-lineBlack&Whitegameareintroducedindetailasfollowed.Thethesishaveafulltouchonserverandclientsocketprogramming,thecommunicationbetweenserverandclientwasimplemented,thealgorithmofthefive-in-a-rowgame,themultimediaplaybackfunctions.
Keywords:On-linegames;Black&Whitegame;VC;WinSocket;MCI
目
1录论文总页数:27页引言.........................1
1.1
1.2网络游戏背景.......................................................1五子棋游戏现状及研究意义..............................1
2游戏开发环境介绍...........................................................1
2.1
2.2
2.3
2.4
2.5环境介绍...............................................................1VisualC++6.0介绍............................................1OSI模型介绍........................................................2TCP/IP模型介绍..................................................2Winsock技术........................................................3
2.5.1
2.5.2
2.5.3
2.5.4Winsock编程流程简介...........................3CAsyncSocket类介绍.............................4CSocket类介绍........................................5多媒体MCI接口介绍..............................6
3五子棋游戏(网络版)研究方法...................................7
3.1
3.2五子棋游戏(网络版)需求分析......................7五子棋游戏(网络版)研究思路......................8
4五子棋游戏(网络版)设计...........................................9
4.1
4.2五子棋游戏(网络版)流程..............................9五子棋游戏(网络版)功能设计方案..............9
4.2.1
4.2.2
4.3主要类介绍...............................................9主要类的工作示意图............................10五子棋游戏实现.................................................10
4.3.1
4.3.2
4.3.3
4.3.4
4.3.5
4.3.6
4.3.7游戏连接——CServerSocket类的实现.......................................................10游戏连接——CClientSocket类的实现.......................................................12网络信息——CMessg类的实现...........14下棋算法——Match类的实现.............14主界面——CFiveChessView类的实现.........................................................16多媒体——CSoundThread类的实现.............................................................22定时器的实现.........................................23
5游戏测试.........................................................................24
5.1
5.2五子棋下棋功能测试.........................................24音乐播放测试.....................................................24
5.3
结定时器以及其他响应测试...........................................................................................25论...........................................................................................................................................25
参考文献...........................................................................................................................................25致
声谢...........................................................................................................错误!未定义书签。明...........................................................................................................错误!未定义书签。
1引言
1.1网络游戏背景
中国民族原创网络游戏为中国网络游戏产业所做出了巨大贡献,民族原创网络游戏已经成为产业发展的主导力量。同样在中国自主研发的民族原创网络游戏已经真正成为中国游戏市场的主导力量。
网络游戏是通过信息网络传播和实现的互动娱乐形式,是一种网络与文化相结合的产业。近年来,网络文化市场发展很快,随着互联网的迅速普及、宽带的接入社区和家庭,我国网络游戏市场发展迅速并进入了一个高速增长期,并已经创造了较大的产值,带动了相关产业的发展,对促进我国网络经济和娱乐业的发展、丰富互联网时代人民群众的文化娱乐生活起到了积极作用。
1.2五子棋游戏现状及研究意义
如今网络上的提供免费五子棋游戏,大多数是单机版的,界面单一,功能单
一。本系统将实现在网络上对战的五子棋功能;同时还整合多媒体功能;还对在下棋界面美化,以及下棋中可能出现的意外进行了处理。这样五子棋休闲游戏将不在是一个功能单一界面枯燥的无声游戏,而是一个较完善的休闲游戏。2游戏开发环境介绍
2.1环境介绍
操作系统:MicrosoftWindowsXP
程序语言:C++
开发工具:VisualC++6.0
2.2VisualC++6.0介绍
VisualC++6.0自诞生以来,一直是Windows环境下最主要的应用开发系统之一。VisualC++不仅是C++语言的集成开发环境,而且与Win32紧密相连,所以,利用VisualC++可以完成各种各样的应用程序的开发,从底层软件直到上层直接面向用户的软件。而且,VisualC++强大的调试功能的为大型复杂软件的开发提供了有效的排错手段。
进入90年代以来,随着多媒体技术和图形图像技术的不断发展,可视化(Visual)技术得到广泛的重视,越来越多计算机专业人员和非专业人员都开始研究并应用可视化技术。所谓可视化技术,一般是指软件开发阶段的可视化和计算机图形技术和方法的应用。可视化编程就是软件开发阶段的可视化。VisualC++6.0是一个很好的可视化编程工具,使用VisualC++6.0环境来开发Windows应用程序大大缩短了开发时间,而且它的界面更友好,便于程序员操作。
开发环境是程序员同VisualC++的交互界面,通过它程序员可以访问C++源代码编辑器、资源编辑器,使用内部调试器,并且可以创建工程文件。
第1页共27页
五子棋游戏(网络版)的设计与开发.doc下载2.3OSI模型介绍
OSI是OpenSystemInterconnect的缩写,意为开放式系统互联。国际标准组织(国际标准化组织)制定了OSI模型。这个模型把网络通信的工作分为7层,分别是物理层,数据链路层,网络层,传输层,会话层,表示层和应用层。1至4层被认为是低层,这些层与数据移动密切相关。5至7层是高层,包含应用程序级的数据。每一层负责一项具体的工作,然后把数据传送到下一层。
如图
1-1:
图1-1OSI模型图
2.4TCP/IP模型介绍
TCP/IP是TransmissionControlProtocol/InternetProtocol(传输控制协议/互联网协议)的缩写。TCP/IP协议使用范围极广,许多厂商的计算机操作系统和网络操作系统产品都采用或含有TCP/IP协议。TCP/IP协议已成为目前事实上的国际标准和工业标准。
TCP/IP也是一个分层的网络协议,不过它与OSI模型所分的层次有所不同。TCP/IP从底至顶分为链路层、网络层、传输层、应用层等4个层次。TCP/IP的分层情况如图1-2
所示。
图1-2TCP/IP模型图
第2页共27页
2.5Winsock技术
Winsock编程流程简介2.5.1
下面介绍一下Win32平台的Winsock编程方法。通讯则必须有服务器端和客户端。简单介绍tcp服务器端的大体流程。
intWSAStarup(WORDwVersionRequested,LPWSADATAlpWsAData)SOCKETsocket(intaf,inttype,intprotocol);
当调用了socket()接口函数创建了一个套接字后,必须把套接字与需要进行通讯的地址建立联系。
intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);structsockaddr_in
{
short
u_short
structin_addr
char
}
就包含了需要建立连接的本地的地址,包括地址族,ip和端口信息;WinsockAPI提供了几个函数,把主机字节转化成网络字节的函数;
u_longhtonl(u_longhostlong);
u_shorthtons(u_shorthostshort);
把网络字节转化成主机字节的函数;
u_longntohl(u_longnetlong);
u_shortntohs(u_shortnetshort);
当绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。
intlisten(SOCKETs,intbacklog);
如果客户端有了连接请求,还必须使用intaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen)来接受客户端的请求。
现在基本上已经完成了一个服务器的建立,而客户端的建立的流程则是初始化WinSock,然后创建socket套接字,再使用intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen)来连接服务端。
当服务器端和客户端建立连接以后,无论是客户端,还是服务器端都可以使用:
intsend(SOCKETs,constcharFAR*buf,intlen,intflags);sin_family;sin_prot;sin_addr;sin_sero[8];
第3页共27页
intrecv(SOCKETs,charFAR*buf,intlen,intflags);
函数来接收和发送数据,因为,TCP连接是双向的。
当要关闭通讯连结的时候,任何一方都可以调用intshutdown(SOCKETs,inthow)来关闭套接字的指定功能。再调用intclosesocket(SOCKETs)来关闭套接字句柄。这样一个通讯过程就算完成了。
2.5.2CAsyncSocket类介绍
微软的MFC把复杂的WinSockAPI函数封装到类里,这使得编写网络应用程序更容易。CAsyncSocket类逐个封装了WinSockAPI,为高级网络程序员提供了更加有力而灵活的方法。这个类基于程序员了解网络通讯的假设,目的是为了在MFC中使用WinSock,程序员有责任处理诸如阻塞、字节顺序和在Unicode与MBCS间转换字符的任务。
CAsyncSocket类编程模型
在一个MFC应用程序中,要想轻松处理多个网络协议,而又不牺牲灵活性时,可以考虑使用CAsyncSocket类,它的效率比CSocket类要高。CAsyncSocket类针对字节流型套接字的编程模型简述如下:
1、构造一个CAsyncSocket对象,并用这个对象的Create成员函数产生一个Socket句柄。可以按如下两种方法构造:
CAsyncSocketsock;//使用默认参数产生一个字节流套接字
Sock.Create();
或在指定端口号产生一个数据报套接字
CAsyncSocket*pSocket=newCAsyncSocket;
intnPort=27;
pSocket->Create(nPort,SOCK-DGRAM);
第一种方法在栈上产生一个CAsyncSocket对象,而第二种方法在堆上产生CAsyncSocket对象;第一种方法中Create()成员函数用缺省参数产生一个字节流套接字,第二种方法中用Create()成员函数在指定的端口产生一个数字报套接字。Create()函数的原型为:
BOOLCreate(UINTnSocketPort=0,intnSocketType=SOCK_STREAM,LPCTSTRlpszSocketAddress=NULL);
该函数的参数有:
1)端口,UINT类型。注意:如果是服务方,则使用一个众所周知的端口供服务方连接;如果是客户方,典型做法是接受默认参数,使套接字可以自主选择一个可用端口。
2)socket类型,可以是SOCK-STREAM(默认值,字节流)或SOCK-DGRAM
第4页共27页
(数据报)。
3)socket的地址,例如"ftp.gliet.edu.cn"或"202.193.64.33"。
2、如是客户方程序,用CAsyncSocket∷Connect()成员函数连接到服务方;如是服务方程序,用CAsyncSocket∷Listen()成员函数开始监听,一旦收到连接请求,则调用CAsyncSocket∷Accept()成员函数开始接收。注意:CAsyncSocket∷Accept()成员函数要用一个新的并且是空的CAsyncSocket对象作为它的参数,这里所说的"空的"指的是这个新对象还没有调用Create()成员函数。
3、调用其他的CAsyncSocket类的Receive()、ReceiveFrom()、Send()和SendTo()等成员函数进行数据通信。
4、通讯结束后,销毁CAsyncSocket对象。如果是在栈上产生的CAsyncSocket对象,则对象超出定义的范围时自动被析构;如果是在堆上产生,也就是用了new这个操作符,则必须使用delete操作符销毁CAsyncSocket对象。
2.5.3CSocket类介绍
为了给程序员提供更方便的接口以自动处理这些任务,MFC给出了CSocket类,这个类是由CAsyncSocket类继承下来的,它提供了比CAsyncSocket更高层的WinSockAPI接口。Csocket类和CsocketFile类可以与Carchive类一起合作来管理发送和接收的数据,这使管理数据收发更加便利。CSocket对象提供阻塞模式,这对于Carchive的同步操作是至关重要的。阻塞函数(如Receive()、Send()、ReceiveFrom()、SendTo()和Accept())直到操作完成后才返回控制权,因此如果需要低层控制和高效率,就使用CasyncSock类;如果需要方便,则可使用Csocket类。
一个CSocket对象代表了一个比CAsyncSocket对象更高层次的WindowsSocket的抽象,CSocket类与CSocketFile类和CArchive类一起工作来发送和接收数据,因此使用它更加容易使用。CSocket对象提供阻塞模式,因为阻塞功能对于CArchive的同步操作是至关重要的。在这里有必要对阻塞的概念作一解释:一个socket可以处于“阻塞模式”或“非阻塞模式”,当一个套接字处于阻塞模式(即同步操作)时,它的阻塞函数直到操作完成才会返回控制权,之所以称为阻塞是因为此套接字的阻塞函数在完成操作返回之前什么也不能做。如果一个socket处于非阻塞模式(即异步操作),则会被调用函数立即返回。在CAsyncSocket类中可以用GetLastError成员函数查询最后的错误,如果错误是WSAEWOULDBLOCK则说明有阻塞,而CSocket绝不会返回WSAEWOULDBLOCK,因为它自己管理阻塞。但在CSocket类中,为了利用CArchive处理通讯中的许多问题和简化编程,它的一些成员函数总是具有阻塞性质的,这是因为CArchive类
第5页共27页
需要同步的操作。
CSocket类编程模型
使用CSocket对象涉及CArchive和CSocketFile类对象。以下介绍的针对字节流型套接字的操作步骤中,只有第3步对于客户方和服务方操作是不同的,其他步骤都相同。
1、构造一个CSocket对象。
2、使用这个对象的Create()成员函数产生一个socket对象。在客户方程序中,除非需要数据报套接字,Create()函数一般情况下应该使用默认参数。而对于服务方程序,必须在调用Create时指定一个端口。需要注意的是,Carchive类对象不能与数据报(UDP)套接字一起工作,因此对于数据报套接字,CAsyncSocket和CSocket的使用方法是一样的。
3、如果是客户方套接字,则调用CAsyncSocket∷Connect()函数与服务方套接字连接;如果是服务方套接字,则调用CAsyncSocket∷Listen()开始监听来自客户方的连接请求,收到连接请求后,调用CAsyncSocket∷Accept()函数接受请求,建立连接。请注意Accept()成员函数需要一个新的并且为空的CSocket对象作为它的参数,解释同上。
4、产生一个CSocketFile对象,并把它与CSocket对象关联起来。
5、为接收和发送数据各产生一个CArchive对象,把它们与CSocketFile对象关联起来。切记CArchive是不能和数据报套接字一起工作的。
6、使用CArchive对象的Read()、Write()等函数在客户与服务方传送数据。
7、通讯完毕后,销毁CArchive、CSocketFile和CSocket对象
2.5.4多媒体MCI接口介绍
多媒体控制接口MCI是MicroSoftWindows定义的多媒体接口标准。MCI向Windows提供高层次的,独立于设备的,控制各种多媒体设备的命令。MCI可以在C语言中直接调用函数库。
对MCI的访问可以通过两种方式:一种是使用消息命令接口函数;另一种是使用字符串接口函数。它们的不同之处在于有着不用的命令结构和发送消息到多媒体设备的不同原理。但是任何一种方式都可以达到同样的效果。
基于字符串多媒体控制接口的编程方式,通过向设备发送字符串实现对多媒体设备的控制。这种方式主要有两个函数MciSendString和MciGetErrorString。
基于消息命令接口函数的编程方式,也就是游戏设计中采用的方式。一条基于消息的MCI命令包括四部分:MCI设备标记、控制消息参数、消息标记、消息数据结构指针。这种方式有三个核心函数MciSendCommand、MciGetDeviceID、
第6页共27页
MciGetErrorString。
就MCI的使用五子棋游戏中,使用基于消息命令接口函数的编程方式,MCI编程具体实现如下:
//音乐文件选择对话框
CStringstrFileName;
CStringsFilter="MP3文件(*.mp3)|*.mp3|Wav文件(*.wav)|*.wav|WMA文件(*.wma)|*.wma||";
CFileDialogfile(TRUE,"","",OFN_FILEMUSTEXIST,(LPCTSTR)sFilter);
if(file.DoModal()==IDOK)//打开对话框
{
strFileName=file.GetPathName();//变量取得文件路径
}
mciOpen.lpstrElementName=
strFileName.GetBuffer(strFileName.GetLength());//传递给MCI标准控件文件路
径
mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpen);//打开文件
m_wDeviceID=mciOpen.wDeviceID;//取得播放设备
mciSendCommand(m_wDeviceID,MCI_PLAY,0,(DWORD)(LPVOID)&mciPlay);//播放音乐
mciSendCommand(m_wDeviceID,MCI_STOP,0,NULL);//停止播放音乐
3五子棋游戏(网络版)研究方法
3.1
?五子棋游戏(网络版)需求分析五子棋游戏基本功能
该功能为程序设计的最基本的功能,程序有服务器端和客户端。当服务器端运行时会自动侦察是否有客户端运行,并自动接入开始游戏。当用户五子连成一线时即赢。
?音乐播放
现在游戏中已经很难找到是无声游戏的,多媒体就成了一个游戏不可缺少的一部分。该功能是多媒体播放功能,在用户游戏时候能随意播放自己喜欢的音乐。声音是提高游戏娱乐性中不可缺少的一环。
?扩展功能
在游戏中当下棋位置不对或者还没有轮到本机下棋能提示用户相应信息。当游戏中用户长时间没有下棋会提示用户该下棋,当对方长时间没有下棋会提示用
第7页共27页
第11 / 29页
户是否继续。
设想如下图
3-1:
图3-1五子棋设想图
3.2五子棋游戏(网络版)研究思路
本毕业设计是利用VC6.0这一集成开发工具,在Windows环境下开发一款休闲网络游戏。本毕业设计通过策划、实现、测试等游戏开发的一般流程。游戏设计是按如下功能模块的设计思路来安排的:
?
据。
客户端模块:负责连接到服务器并处理和服务器的会话。
游戏规则模块:负责游戏的控制和结果的判断,使游戏按规则进行。
视图控制模块:负责控制整个程序的操作,负责处理用户的输入和游戏的界面绘制。
?多媒体功能设计模块:
音频播放模块:负责播放MP3,WMA等格式的音乐。
效果如图3-2:五子棋游戏设计可以分成如下几个模块:服务器模块:负责建立游戏服务器并接受客户端的连接和处理客户端的数
第8页共27页
图3-2五子棋游戏(网络版)效果图
4五子棋游戏(网络版)设计
4.1
五子棋游戏(网络版)流程
图4-1五子棋游戏(网络版)流程图
4.2
4.2.1五子棋游戏(网络版)功能设计方案主要类介绍
CServerSocket类:是一个专门用来监听客户端连接的Socket类。当游戏运行,选择了开启服务器之后,即调用本类来初始一个Socket对象。这个Socket对象将负责监听网络上有没有客户端连接到来。
CClientSocket类:是一个专门用做会话类,它负责数据的发送和接受。当游戏运行,选择了连接服务器之后,即调用本类来初始一个Socket对象。这个
第9页共27
页
对象是用来连接服务器,它连接上以后,就可以通过他进行数据的交换。
CMessg类:是一个数据类,它发挥串行化数据的作用。它就是用来在网络上传输的信息。
Match类:是一个规则类,它负责游戏规则的处理。在游戏运行中,它保存着一个二维数组记录当前棋盘的信息,它还负责判断能否在某个位置下棋,是否有人赢棋。
CFiveChessView类:是游戏的主视图类。在游戏中它负责在主窗口中绘制盘和棋子。以及鼠标消息的处理。
CClientDlg类:是游戏中客户端设置的对话框类。在游戏中,选择打开连接服务器时,弹出来的连接服务器对话框。
CServerDlg类:是游戏中服务器端设置的对话框类。在游戏中,选择打开开启服务器时,弹出的开启服务器对话框。
CSoundThread类:是游戏中负责多媒体播放的线程类,主要负责音乐播放。当然了它实现了播放和关闭,也就是线程的开启和终止。
4.2.2
主要类的工作示意图
图4-2主要类工作示意图
4.3五子棋游戏实现
游戏连接——CServerSocket类的实现4.3.1
这是一个专门用来监听客户端连接的Socket类,它继承于CSocket,响应OnAccept消息。所需要的参数从对话框中取得,如图4-3:
第10页共27页
图4-3服务器端设置图
CServerSocket类需要声明一个主视图指针,为接受连接函数服务。并且在类成员函数Init(UINTport,CFiveChessView*dlg)中负责监听SOCKET和创建SOCKET。当用户选择“开启服务器”功能时,程序就会工作在服务器端模式,并且不停的监听是否有客户端的连接。当有监听客户端的连接消息时,OnAccept函数响应。
BOOLCServerSocket::Init(UINTport,CFiveChessView*view)
{m_uPort=port;
m_view=view;
if(Create(m_uPort)==FALSE)//创建SOCKET
{AfxMessageBox("ServerSocketCreateError");
returnFALSE;
}
if(this->Listen()==FALSE)//监听SOCKET
{
AfxMessageBox("ServerListenError");
returnFALSE;
}
returnTRUE;
}
voidCServerSocket::OnAccept(intnErrorCode)//授受客户端请求
第11页共27
页
第15 / 29页
{
CSocket::OnAccept(nErrorCode);
m_view->ProcessPendingAccept();//调用视图类中连接处理函数
}
4.3.2游戏连接——CClientSocket类的实现
这是一个专门用做会话类,它负责数据的发送和接受。她继承于CSocket,负责响应OnReceive和OnClose消息。另外,作为CSocket类的继承类,当然采用了串行化方式来处理网络数据。网络数据由CMessg对象构成。连接服务器所需参数通过对话框获得,如图
4-4:
图4-4客户端设置图
CClientSocket类中需要数据串行化网络数据。类初始化成员Init函数负责Socket和串行化相关的初始化;成员函数GetIpAddress用于获得本地IP;成员函数GetLocalHostName用于获得本地计算机名称;当连接上服务器以后,使用SendMessage(CMessg*msg)发送消息,或者使用OnReceive(intnErrorCode)接收对方发送过来的数据,并对数据进行处理。当关闭客户端Socket是使用成员函数CloseSocket关闭。
voidCClientSocket::OnReceive(intnErrorCode)
{
CSocket::OnReceive(nErrorCode);
do
{
CMessgtemp;
第12页共27页
temp.Serialize(*m_aSessionIn);//输入数据串行化
//判断对方发送过来的数据是否是落子的位置
if(m_view->m_match.CanDown(temp.m_x,temp.m_y,m_view->m_who%2+1))
{//是对方落子的信息
m_view->m_turn=temp.m_turn;//轮到我下
m_view->Invalidate(FALSE);//刷新视图,显示对方的走子位置
if(m_view->m_match.IsWin(m_view->m_who%2+1,m_view->m_winpos))
{
m_view->m_bWin=TRUE;//对方赢
m_view->m_bOver=TRUE;
m_view->Invalidate(FALSE);
AfxMessageBox("SORRY,你输了");
}
}
}
while(!m_aSessionIn->IsBufferEmpty());
}
BOOLCClientSocket::SendMessage(CMessg*msg)
{
if(m_aSessionOut!=NULL)
{
msg->Serialize(*m_aSessionOut);//输出串行化
m_aSessionOut->Flush();//直接发送
returnTRUE;
}
else
{
//对方关闭了连接
m_bClose=true;
CloseSocket();
returnFALSE;
}
}
第13页共27页
4.3.3网络信息——CMessg类的实现
这是一个数据类,继承于CObject.它主要负责串行化数据的作用。CMessg类主要的成员变量:
int
int
intm_turn;m_x;m_y;
其中m_turn表示轮到谁走棋;m_x表示落子的水平位置;m_y表示落子的竖直位置。这3个数据就是网络要传的数据。
其中数据串行化实现如下:
voidCMessg::Serialize(CArchive&ar)
{
if(ar.IsStoring())
{
ar<<m_turn;
ar<<m_x;
ar<<m_y;
}
else
{
ar>>m_turn;
ar>>m_x;
ar>>m_y;
}
}
4.3.4下棋算法——Match类的实现
这是一个规则类,它负责规则的处理。在Match中保存着一个当前的棋盘,用的一个chessboard[LW][LW]。如果数组元素为0,则表示没有棋子;如果为1,则表示有黑子,如果为2,则为白子。Match负责是否能下子,是否有人赢棋。
Match中类LW定为19,表示有19行19列。既然Match中保存着一个当前棋盘,那就需要有一个判断的成员函数,只有chessboard为0时才能落子,类中使用成员函数CanDown(intx,inty,intwho)判断能否落子。并且有一个判断是否赢的成员函数IsWin(intwho,intpos[5][2]);其中pos[5][2]为记录赢的关键棋子。最后还有一个清除棋盘也就是把所有的chessboard全部设置为0的函数Clear。算法执行出来的结果,如图4-5:
第14页共27页
图4-5赢棋图
五子棋的核心算法IsWin主要是判断了水平、垂直、东南、东北四个方向是否有五子相连;它们判定条件可以表示为;
水平:
chessboard[i][j+1]==who&&chessboard[i][j+2]==who&&chessboard[i][j+3]==who&&chessboard[i][j+4]==who
垂直:
chessboard[i+1][j]==who&&chessboard[i+2][j]==who&&chessboard[i+3][j]==who&&chessboard[i+4][j]==who
东南:
chessboard[i+1][j+1]==who&&chessboard[i+2][j+2]==who&&chessboard[i+3][j+3]==who&&chessboard[i+4][j+4]==who
东北:
chessboard[i-1][j+1]==who&&chessboard[i-2][j+2]==who&&chessboard[i-3][j+3]==who&&chessboard[i-4][j+4]==who
作为说明,以水平方向判定为例子;
BOOLMatch::IsWin(intwho,intpos[5][2])
{inti,j;
for(i=0;i<LW;i++)
for(j=0;j<LW;j++)
{
if(chessboard[i][j]==who)
{
第15页共27
页
if(j+4<LW)//水平
{
if(chessboard[i][j+1]==who&&chessboard[i][j+2]==who&&chessboard[i][j+3]==who&&chessboard[i][j+4]==who)
{
for(intk=0;k<5;k++)
{
pos[k][0]=i;
pos[k][1]=j+k;
}
returnTRUE;
}
}
//垂直,像水平方向那样添加条件即可
//东南,像水平方向那样添加条件即可
//东北,像水平方向那样添加条件即可
}
}
returnfalse;
}
4.3.5主界面——CFiveChessView类的实现
CFiveChessView是程序的主视图类。CFiveChessView类也是本程序中相当重要的一个类。它实现了棋盘、棋子的绘制之外,程序界面的美化,还有鼠标消息的处理等。显示主界面,如图4-6:
第16页共27页
图4-6主界面图
首先游戏初始化当然包括Winsock的初始化,获得本机的IP地址,以及相关的状态变量的初始化。其中状态变量包括m_bIsClient表示是否客户端、m_bIsInit表示是否已经初试化、m_bWinm_bOver表示是否结束、m_turn表示轮到谁走棋等。这是因为初始只需要调用一次。
开始游戏时有作为客户端运行的“连接服务器”或者作为服务器端“开启服务器”两个选项。
?当选择作为服务器端“开启服务器”时,游戏创建一个CServerDlg类对话框,并由对话框获得输入的端口号信息,由于在游戏初始化时Winsock已经初始化。这里直接调用CServerSocket类创建一个socket监听端口。程序功能实现如下:
voidCFiveChessView::OnSetserver()
{
CServerDlgdlg;
//服务器端口设置对话框
if(dlg.DoModal()==IDOK)
{
m_bIsClient=FALSE;//作为服务器
m_bIsInit=TRUE;//已经初试化
m_port=dlg.m_iPort;//得到输入端口号
m_ListenSocket.Init(m_port,this);//开始监听端口
}
第17页共27
页
}
服务器端当监听到有客户端需要连接时,有成员函数ProcessPendingAccept接受客户端的连接处理。ProcessPendingAccept函数实现如下:
voidCFiveChessView::ProcessPendingAccept()
{
if(m_ListenSocket.Accept(m_ClientSocket)==FALSE)//分配一个会话SOCKET
{
AfxMessageBox("ServerListenSocketError");
return;
}
else
{
m_who=1;//服务器端用黑子
m_ClientSocket.Init(this);//初试化会话SOCKET
AfxMessageBox("嘿嘿,有人进来挑战了");
}
}
?当选择作为客户端“连接服务器”时,游戏创建一个CClientDlg类对话框,并由对话框获得输入的IP信息、端口号信息,由ClientSocket.Create()创建会话socket,并连接服务器。游戏设计中具体响应函数OnSetclient如下:
voidCFiveChessView::OnSetclient()
{
//TODO:Addyourcommandhandlercodehere
CClientDlgdlg;
intret=dlg.DoModal();//设置服务器IP和端口
if(ret==2000)//用户确定
{
m_bIsClient=TRUE;//作为客户端
m_bIsInit=TRUE;
m_port=dlg.m_iPort;//得到用户输入的端口号
for(inti=0;i<4;i++)//得到输入的服务器IP地址
m_bIP[i]=dlg.m_bIP[i];
m_ip.Format("%d.%d.%d.%d",dlg.m_bIP[0],dlg.m_bIP[1],dlg.m_bIP[2],dlg.m_bIP[3]);
m_ClientSocket.Create();//创建会话SOCKET
第18页共27页
久久建筑网m.kkreddy.com提供大量:建筑图纸、施工方案、工程书籍、建筑论文、合同表格、标准规范、CAD图纸等内容。