vc++四国军棋系统设计与实现(源代码+论文)
收藏
资源目录
压缩包内文档预览:
编号:149740982
类型:共享资源
大小:3.02MB
格式:RAR
上传时间:2021-10-10
上传人:好资料QQ****51605
认证信息
个人认证
孙**(实名认证)
江苏
IP属地:江苏
20
积分
- 关 键 词:
-
vc
国军
系统
设计
实现
源代码
论文
- 资源描述:
-
vc++四国军棋系统设计与实现(源代码+论文),vc,国军,系统,设计,实现,源代码,论文
- 内容简介:
-
目录第一章 绪论11.1 问题概述11.1.1 问题的来源11.1.2 目的和意义11.1.3 国内外研究现状11.2 问题剖析21.2.1 主要问题21.2.2 难点和关键31.2.3 思路和方法3第二章 相关的知识和工具42.1 解决问题的知识基础42.2 开发平台52.3 数据库5第三章 总体设计63.1 总体设计的框架63.2 模块功能概述73.3 关键算法83.4关键技术12第四章 详细设计144.1数据库结构144.2模块结构144.3 重要模块详述15第五章 程序编码195.1 数据结构195.2主要界面225.3 重要模块程序实现24第六章 问题和展望326.1 特色与成功326.2 问题与展望32参考文献33附录34游戏大厅34游戏类38绪论第一章 绪论1.1 问题概述1.1.1 问题的来源随着Internet的普及,网络游戏已经成为大家耳濡目染的新生事物。网络游戏从出现到现在的发展的时间很短,但是其发展速度却非常之快。现在,可以说网络游戏已经成为人们休闲、娱乐的有效方式。国内比较有名气的网络游戏有联众网络游戏世界()、qq游戏中心()、中国游戏中心() 以及这几年受玩家亲睐的传奇、魔兽世界等。1.1.2 目的和意义对当今网络游戏的设计、架构进行分析、探索和实践。提供友好的客户操作界面,通过客户端与服务器之间的网络传递数据,实现了多人协同游戏的目的。分析现今网络游戏体系结构及设计模式的优缺点,及对网络游戏的发展给予分析和展望。1.1.3 国内外研究现状现今网络游戏的体系结构(见图1-1),包括客户机程序、服务器程序、数据库服务器。图1-1 网络游戏体系结构1.2 问题剖析1.2.1 主要问题在开发网络游戏时,首先要建立底层的网络通信类,利用网络通信类连接构建客户服务器之间的TCP/IP连接,然后在该连接的基础上利用自设定的协议进行客户端登录、进行游戏等操作。在以上协议的基础上,根据不同的游戏编写不同的游戏逻辑处理类,在该逻辑处理类中实现了对应的游戏逻辑,如实例中的军棋,则实现相互之间的对弈等功能。同时在服务器端还需要和数据库服务器交互,用于读取或保存客户信息(如用户积分、密码、个人资料等数据)。1.2.2 难点和关键1、有一个或多个游戏服务器启动特定游戏服务。2、游戏者到游戏网站上下载客户端程序并且申请游戏账号ID。然后启动客户端程序通过某种网络协议连接游戏服务器。3、客户端程序负责处理客户端显示和操作界面,具有简单的逻辑处理功能,同时负责接收发送与服务器端交互的数据包。4、服务器程序负责处理服务器端逻辑、游戏逻辑、客户之间的网络信息传递,以及数据库之间的数据读取保存工作。同时服务器端还要承担客户端数据的接收、转发工作。1.2.3 思路和方法网络游戏通常的运行方式(见图1-2)。图1-2 网络游戏交互图 - 3 - 相关的知识和工具第二章 相关的知识和工具2.1 解决问题的知识基础网络游戏常用的网络协议有适用于Internet的TCP/IP协议、适用局域网(比如星际)的IPX协议。(一) TCP/IP协议TCP/IP协议(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是Internet中计算机进行通信的标准,其命名起源于该组协议中最重要的两个协议TCP和IP。任何关于Internet协议的讨论必须由TCP/IP开始,它也是其他所有协议的基础。TCP/IP协议是Internet网络的共同语言,主机之间必须利用TCP/IP互通信息。TCP/IP协议目前已经成为发展最成功的通信协议之一,它起源于20世纪60年代末美国政府资助的一个分级交换网络研究项目,允许分布在各地的使用不同操作系统的网络进行通信。随着世界范围个人电脑的普及,日常无论收发邮件、访问网页和文件传输都已经离不开TCP/IP协议,TCP/IP协议已经成为Internet的基础。(二) TCP/IP结构TCP/IP实际上就是在物理网上的一组完整的协议。其核心部分是传输层协议(TCP/UDP)、网络层(IP)和物理接口层,这三层通常在操作系统内核中实现。TCP/UDP层提供了传输层服务,而IP协议提供了网络层服务。TCP/IP协议是一个四层协议,其结构如图2-1所示。图2-1 TCP/IP协议体系结构图应用程序与TCP/IP可靠传输之间接口具有五大特性: 面向数据流当两个用户进程传输大量数据时,我们把这些数据当做可划分为八位组(octer,字节)的比特流,在目的机器上运行的数据流投递服务软件提给接收方的八位组与信源机上发送方送出来的完全相同。 虚电路连接数据流的传输与电话相似,使用“虚电路”这个术语来描述这种连接是因为在应用程序看来这种连接像是一条专用的硬件电路,这种可靠连接的错觉是由数据流投递服务提供。 有缓冲的传送使用虚电路服务来发送数据流的应用程序不断向协议软件递交数据八位组。为了提高效率以及减少网络延迟,协议软件在实现时都会从数据流中收集到足够多的数据,组成大小合理的数据包后再送到网络上传输。 无结构的数据TCP/IP协议并不区分结构化的数据流。使用数据流的应用程序必须在开始连接之前就了解数据流的内容并对其格式进行协商。这点很重要,在程序中表现为send函数只能发送字符串,这就需要将接收的字符串转化需要的结构化的数据。 全双工连接TCP/IP流服务所提供的功能是双向的全双工连接。其中包括了两个独立、流向相反的数据流,而这两个数据流之间不进行显式的交互。常用协议主要包括TCP/UDP层协议和IP层协议。TCP和UDP都是传输层协议,都使用IP协议作为网络层协议。使用UDP协议的应用程序必须承担可靠性的工作,包括报文的丢失、重复、乱序以及连接失效等问题,而程序员编程时则容易疏忽。2.2 开发平台操作系统Windows 2000, 开发工具VisualC+6.0。 2.3 数据库SQL Server 2000,是一个全面的数据库平台,引擎为关系型数据和结构化数据提供了安全可靠的存储功能。 - 5 - 总体设计第三章 总体设计3.1 总体设计的框架军棋游戏的总体设计框架,客户端如图3-1所示。图3-1 军棋游戏架构客户端军棋游戏的总体设计框架,服务器如图3-2所示。图3-2 军棋游戏架构服务器3.2 模块功能概述客户端类的划分: 游戏基本类:负责处理游戏中一些完成基本功能的类,如处理声音类、处理动画图标,图形按钮等类,基本类的特点是被其他类在特定处所调用,并不动生成对象。 游戏框架类:负责处理游戏中客户端用于显示程序界面和绘制游戏界面以及显示用户信息和广告信息等处理任务。 游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间的透明的效果。 游戏应用程序类:主要负责处理应用程序中各种设置显示对话框、程序主线程处理、程序中基本的运行类框架的管理,以及游戏中图形的处理和显示等任务的处理。 游戏处理类:主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行中维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。服务器类的划分: 游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间透明传输的效果。 游戏协议类:负责处理游戏中客户服务器之间交互所传递的数据,并且对该数据格式进行打包和解包,同时根据该包中所包含的指令串进行相应的操作。 游戏逻辑类:负责处理游戏逻辑,如军棋游戏中用于维护军棋逻辑,判断下棋,得分等处理类。 用户管理类:用于管理用户资料,在用户登录后通过数据库验证用户名和密码,通过验证后从数据库读取用户的详细资料。同时在程序中维护用户数据,在用户游戏结束和退出游戏时将用户数据保存到数据库中。 服务器框架类:用于管理游戏大厅的数据,包括一些数据的列表。 数据库类:用于网络游戏的服务器端在处理大量的客户资料时,使用数据库进行大量数据的存储和查询所调用的类方法。3.3 关键算法 模块间的数据传递设计,如图3-3所示。图3-3 模块间的数据传递设计这样,在CTableView和CGameDlg中通过指针,也可向服务器发送消息。而CCGameHallFrameView收到消息后,同时也控制CTableView和CGameDlg的行为。采用内存作图的方式,消除了闪烁。首先创建一个内存dc,将绘图的工作先在内存dc中做好,再贴到实际dc上去。做法如下:首先创建关于屏幕的内存DC,代码为MemDC.CreateCompatibleDC( pDC); 之后创建一幅关于屏幕DC的图画,部分代码如下: CRect rect; this-GetClientRect(rect); CBitmap bmpFace; bmpFace.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height();注意把握rect的尺寸为客户区域大小; 之后将这幅画选入内存DC中,部分代码如下: CBitmap* pOldBmp = NULL; pOldBmp = MemDC.SelectObject(&bmpFace); 之后可以开始在内存DC中进行任何绘制动作;部分代码如下: CBrush brush(RGB(255,255,255); MemDC.FillRect(rect,&brush); for(int i=0;iBitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); 最后进行相关的资源回收动作,部分代码如下: MemDC.SelectObject(pOldBmp); bmpFace.DeleteObject();。 同时我们要把系统的ON_WM_ERASEBKGND消息函数重载为return FALSE,否则还是会出现闪烁情况。 在对话框中用这个方法的时候,要注意将有控件的部分和需要绘图的部分分开,可采用如下方法,部分代码如下:CRect rectClient;CRgn rgn1,rgn2;/rgn3,rgn4;GetClientRect(rectClient); rgn1.CreateRectRgnIndirect(rectClient);rgn2.CreateRectRgn(730,0,962,670);if(rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR) = ERROR)return; MemDC.FillRgn(&rgn1,&brush);服务器对连接的用户数据的数据结构的设计,用下面两个结构:typedef struct TTint d4;int ID4;int board1717;BOOL begin4;typedef struct MMCString name,sex;int score;连接的socket保存在如下链表中:typedef CList SOCKET_ARRAY;SOCKET_ARRAY m_connectionList;与服务器建立连接后,相应的用户数据,保存在MM结构数组中,位置为其socket在m_connectionList中的相应位置,这样就可以通过连接的socket找到相应的信息。TT是保存大厅数据的结构,d表示四个坐位有没有人,ID表示就坐的人的socket在链表中的位置。board为棋盘数据。每个桌子有每个桌子的棋盘数据,互不干扰。随着游戏的进行而不断更新。begin表示四个玩家有没有下调度完成的指令。应用矩阵的变换实现坐标旋转。不管你坐在哪个方位,玩游戏时,你始终是在正下方,这就需要实现虚拟坐标到目标坐标的旋转变换,如图3-4。图3-4 坐标图X为实际坐标,x为虚拟坐标,转换公式推导如下,见图3-5。图3-5 坐标变换公式推导direct 为自己座位方向,switch(direct)case 0: (a=90o) X,Y,1=-y+16,x,1 /东case 1:(a=0o) X,Y,1=x,y,1 /南case 2:(a=-90o) X,Y,1=y,-x+16,1 /西case 3:(a=180o) X,Y,1=-x+16,-y+16,1 /北回溯法求工兵路径,军棋游戏逻辑不复杂,只有工兵能够自由飞行。在这里没有求工兵起点到目标点的最短路径,而只是用回溯法求出其中一条路径,所以在游戏中你会发现工兵有时候会绕些弯路。这和老鼠走迷宫差不多的。工兵迷宫数组:int RAILWAY1717=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,3,1,3,1,1,0,0,0,0,0,0,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1,0,0,1,0,0,0,2,2,0,2,0,2,2,0,0,0,1,0,0,1,0,0,0,1,1,3,1,3,1,1,0,0,0,1,0,0,1,0,0,0,2,2,0,2,0,2,2,0,0,0,1,0,0,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1,0,0,0,0,0,0,1,1,3,1,3,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0表示该位置不在工兵铁道上,1表示在该位置可向上下左右方向移动,2表示在该位置只能向上下方向移动,3表示在该位置只能向左右方向移动。3.4关键技术网络通信,Windows Socket 编程接口:Windows Socket (简称WinSock)是在Win32平台上访问基层网络协议的接口。在不同的Win32平台上,Windows Socket以不同的方式存在着,作为网络编程接口而不是协议存在。套接字(Socket)概念,套接字是从英文单词Socket翻译而来,它是网络通信的基本操作单元,是应用层到传输层的接口,可以将套接字看作不同主机间的进程进行双向通信的端点。Windows Socket组成部分,Windwos Sockets实现一般都由两部分组成:开发组件和运行组件。开发组件是供程序员开发Windows Sockets应用程序使用的,主要是WinSock.h头文件。对于Windows Sockets应用程序的源文件来说,只要包括WinSock.h就可以了。除此之外,在使用WinSock的项目中还需要加入WinSock API引入库wsock32.lib。运行组件是Windows Sockets应用程序接口的动态连接库(DLL),文件名为WinSock.dll,应用程序在执行时通过装入它实现网络通信功能。Windows Sockets编程的基本模式,要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户端,我们称之为ClientSocket,另一个运行于服务器端,我们称之为ServerSocket。使用Socket进行网络通信一般有两种方式:基于面向连接的流方式和基于无连接的数据报方式。面向连接的的流方式调用过程如图3-6所示。图3-6 面向连接的流方式调用过程 - 13 -详细设计第四章 详细设计4.1数据库结构服务器端数据库结构如表4-1。User列名数据类型长度允许空描述主键namechar10no用户名codechar10no密码scoreint4yes游戏积分sexchar2yes性别表4-1,玩家信息用作记录玩家游戏数据。4.2模块结构客户端模块结构: 游戏基本类,该类包中包括CBorderButton、CClockObject、CWave类。 游戏框架类,该类包中包括CMainFrame、CCGameHallFrameView、CHtmlViewEx、CTableView类。 游戏通信类,该类包中包括CClient类。 游戏应用程序类,该类包包括CGameDlg类,其中包括对游戏处理类的调用。 游戏处理类,该类包中主要包括TakeGame类。服务器模块结构: 游戏通信类,由CServer类实现。 游戏协议类,由CServerProtocol类实现。 游戏逻辑类,由CServerLogic类实现。 数据库类,由CServerFrameSet类实现。 用户管理类,由CServerFrameView类实现。 服务器框架类,由CServerFrame类实现。4.3 重要模块详述客户端模块: CBorderButton 类是带有边框的图片按钮类,CClockObject 类是时钟类,CWave是用来播放声音的类,当游戏用户下棋,吃子,起身或坐下时要播放声音,选择在程序中调用API函数PlaySound直接播放在资源中的声音文件。模块描述如图4-1。图4-1 游戏基本类模块描述 CMainFrame类是游戏窗口中的游戏大厅框架类,其中包括构架广告显示窗口,可玩的游戏类、工具栏、游戏桌的信息、显示信息等,CCGameHallFrameView类是用来在游戏大厅窗口左侧显示可以玩的游戏以及游戏室,采用树状结构显示。CHtmlViewEx类用于构造广告显示窗口,用于游戏框架中显示广告页。CTableView显示包含游戏桌的游戏大厅,在大厅中多人在等待开始游戏。模块描述如图4-2。图4-2 游戏框架类模块描述 游戏通信类,CClient,功能为建立和服务器的连接,能及处理通信,采用异步机制,以自定义消息事件处理通信等功能。采用自定义消息:WM_USER + 101。模块描述如图4-3。图4-3 游戏通信类模块描述 游戏应用程序类,CGameDlg,其中包括对游戏处理类的调用。CGameDlg 主要负责处理应用程序中各种设置显示对话框、程序主线程处理、以及游戏中的图形的处理和显示等任务的处理。模块描述如图4-4。图4-4 游戏应用程序类模块描述 游戏处理类,TakeGame主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行时维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。模块描述如图4-5。图4-5 游戏处理类模块描述服务器模块: 游戏通信类,由CServer类实现。负责处理游戏中客户与服务器之间的网络连接细节,从而使得对于客户和服务器之间的数据传输可以忽略通信细节。模块描述如图4-6。图4-6 游戏通信类模块描述 游戏协议类,由CServerProtocol类实现。游戏协议类负责解析客户/服务器端所传输的协议,同时根据不同的协议调用不同的操作函数,并根据用户状态变化维护用户信息。模块描述如图4-7。图4-7 游戏协议类模块描述 游戏逻辑类负责处理游戏逻辑,在军棋游戏中包括计算得分,计算赢等。游戏逻辑类CServerLogic和游戏协议类分离的优点是可以只通过修改逻辑类来改变为不同的网络游戏,如修改为“象棋逻辑”即可以成为象棋游戏,修改为“升级逻辑”即可以成为升级游戏。 用户管理类,直接在CCServerFrameView中实现。 数据库类,采用SQL Server 2000数据库,只是用来保存玩家的资料等一些数据。采用MFC ODBC数据库编程,在程序中为CServerFrameSet类。正如MFC提供的其他类库很好地对相应的Win32 API作了封装,MFC提供的ODBC类库也相应地对ODBC API作了封装,通过提供一种高级接口而避免直接使用ODBC API所涉及的种种繁琐处理,简化了对ODBC数据库的应用程序编程。模块描述如图4-8。图4-8 数据库类模块描述- 17 -程序编码第五章 程序编码5.1 数据结构 用1717的数组表示军棋的棋盘,如下:int BOARD1717 = -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,0,0,0,0,0, 0,-1,-1,-1,-1,-1,0,0,0,0,0,0, 0, 0, 0, 0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,-1, 0,-1,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,-1, 0,-1,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0,0, 0,0,0,0,0,0,-1,-1,-1,-1,-1, 0, 7, 3, 4,5, 3, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10, 0, 1,0, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 8,10, 0,1, 5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 6, 0, 4,0, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2, 7, 6,1,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,12,11,2, 2,-1,-1,-1,-1,-1,-1,;1表示棋盘以外的位置0 表示棋盘内位置,但无棋子1 工兵2 排长3 连长4 营长5 团长6 旅长7 师长8 军长9 司令10 炸弹11 地雷12 我方军旗13 上方盟友或敌方的棋子14 左边敌方的棋子15 右边敌方的棋子16 上方军旗17 左方军旗18 右方军旗为了处理工兵的走法的方便,将四个转角斜对的位置恒置为0,这样在为工兵寻找路径时会方便一些。 游戏协议以char(20)作为一次信息的起始点,终点。“”在字符串中用空格代替。以一字符串作为向服务发出的请求信息,服务器也以相应的一字符串发送回客户端作为应答。对话:A桌子号聊天内容坐下:B桌子号方位调度完成:C桌子号方位(棋盘数据)用一维数据形式表示65的二维数组,数据之间用空格开。开始游戏:(只由服务器发出)D对战类型下棋:E 桌子号方位起点(x,y)终点(x,y)吃:(只由服务器发出)(包括移动)F 起点(x,y) + 终点(x,y)被吃:(只由服务器发出)G 起点(x,y) + 终点(x,y)炸:(只由服务器发出)H 起点(x,y) + 终点(x,y)输:离开:(包括断线)投降:I 方位 求和:K 桌子号方位注册:L 用户名密码注册成功:M + 用户名登录:N + 用户名密码登录结果:O + 1/0离开:P + 桌子号 方位请求接收信息:Q + 桌子号 方位碰:R 起点(x,y) + 终点(x,y)5.2主要界面服务器界面如图5-1所示。图5-1 服务器启动界面客户端大厅界面如图5-2所示。图5-2 客户端大厅界面军棋游戏界面,如图5-3所示:图5-3 军棋游戏界面5.3 重要模块程序实现 客户端三拆分窗口的实现BOOL CMainFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) if(NULL=m_wndSplitter.CreateStatic(this,1,2)return FALSE;if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CTableView),CSize(620,800),pContext)return FALSE;if(NULL=m_wndLeftSplitter.CreateStatic(&m_wndSplitter,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0,1)return FALSE;if(!m_wndLeftSplitter.CreateView(0,0,RUNTIME_CLASS(CCGameHallFrameView),CSize(380,300),pContext)|!m_wndLeftSplitter.CreateView(1,0,RUNTIME_CLASS(CHtmlViewEx),CSize(380,500),pContext)return FALSE;pWebView=(CHtmlViewEx*)m_wndLeftSplitter.GetPane(1,0);pServerTreeView=(CCGameHallFrameView*)m_wndLeftSplitter.GetPane(0,0)pTableView=(CTableView*)m_wndSplitter.GetPane(0,0);pServerTreeView-pTable=pTableView;pWebView-Navigate2(/zhou207,0,NULL);return TRUE; 客户端初始化及连接void CClient:ClientInit()if(WSAAsyncSelect(m_hSocket,m_hWnd,CLI_MESSAGE,FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT)0)AfxMessageBox(Error in select);BOOL CClient:InitAndConnect(HWND hWnd, UINT port, CString strServer)m_hWnd=hWnd;m_uPort=port;m_strServer=strServer;if(m_hSocket!=NULL)/先将以前打开的套接字关闭closesocket(m_hSocket);m_hSocket=NULL;/创建面向连接的socketm_hSocket=socket(AF_INET,SOCK_STREAM,0);ASSERT(m_hSocket!=NULL);ClientInit();/设置连接信息:网络协议IP地址端口m_addr.sin_family=AF_INET;m_addr.sin_addr.S_un.S_addr=inet_addr(m_strServer.GetBuffer(0);m_addr.sin_port=htons(m_uPort);/连接服务器int ret=0;int error=0;ret=connect(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr);if(ret=SOCKET_ERROR)/连接失败if(GetLastError()!=WSAEWOULDBLOCK)AfxMessageBox(_T(请确认服务器确实已经打开并工作在同样的端口!);return FALSE;return TRUE; 服务器初始化及连接void CServer:ServerInit()/设置socket的异步模式if(WSAAsyncSelect(m_hSocket,m_hWnd,SER_MESSAGE,FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)0)AfxMessageBox(error select);BOOL CServer:InitAndListen(HWND hWnd, UINT port)m_uPort=port;m_hWnd=hWnd;if(m_hSocket!=NULL)/先关闭已经打开的socketclosesocket(m_hSocket);m_hSocket=NULL;/创建面向连接的流方式的套接字m_hSocket=socket(AF_INET,SOCK_STREAM,0);ASSERT(m_hSocket!=NULL);ServerInit();m_addr.sin_family=AF_INET;m_addr.sin_addr.S_un.S_addr=INADDR_ANY;m_addr.sin_port=htons(m_uPort);int ret=0;int error=0;/绑定套接字到本机的某个端口ret=bind(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr);if(ret = SOCKET_ERROR)AfxMessageBox(Binding Error);return FALSE;ret = listen(m_hSocket, 64);if(ret = SOCKET_ERROR)AfxMessageBox(Listen Error);return FALSE;return TRUE; 回溯法寻找工兵路径BOOL TakeGame:TakeEngineer(CPoint from, CPoint to)POS p;int x,y;engineer=TRUE;p.d=0;p.x=from.x;p.y=from.y;top=0;if(RAILWAYp.xp.y=2)p.d=1;stacktop=p;int f1717;while(top=0)p=stacktop;if(p.x=to.x&p.y=to.y)return TRUE;if(p.dDoModal()=IDOK)name=login-m_name;code=login-m_code;ServerIP=login-m_ServerIP;if(name=|code=|ServerIP=)MessageBox(每项内容都不能为空);elser=1;delete login;elseregister1=new CRegister1();if(register1-DoModal()if(register1-m_code1=register1-m_code2)code=register1-m_code1;sex=register1-m_sex;ServerIP=register1-m_IP;if(code=|sex=|ServerIP=)MessageBox(每项内容都不能为空);elser=2;delete register1;if(r=1|r=2)if(ClientConnect()=TRUE)/m_Init=TRUE;/pTable-flag=1;/pTable-DrawTable();pTable-pClient=&m_client;if(r=1)ClientMessage(N);else if(r=2)ClientMessage(L);*pResult = 0;void CCGameHallFrameView:OnSize(UINT nType, int cx, int cy) CFormView:OnSize(nType, cx, cy);/ TODO: Add your message handler code hereif( m_wndTree.m_hWnd ) / Fill the whole Client Area of the View with the Control m_wndTree.MoveWindow( 0, 0, cx, cy ); LRESULT CCGameHallFrameView:OnClientMessage(WPARAM wParam, LPARAM lParam)char s1024,k;int len;CString str;switch(lParam)case FD_CONNECT:len=GetLastError();if(len!=0)AfxMessageBox(Error in Connecting);elsem_Init=TRUE;return 0;case FD_READ:len=recv(m_client.m_hSocket,s,1024,0);slen=NULL;str=s;k=protocol.Anaysys(str);dealMessage(k);return 0;case FD_WRITE:return 0;case FD_CLOSE:return 0;default:MessageBox(服务器已关闭!);return 0;BOOL CCGameHallFrameView:ClientConnect()if(m_client.InitAndConnect(m_hWnd,PORT,ServerIP)=FALSE)return FALSE;return TRUE;char CH=char(20);void CCGameHallFrameView:ClientMessage(char k)CString str;str=CH;str+=k;switch(k)case L:str+=code;if(sex=女)str+= 2;elsestr+= 1;str+=CH;/MessageBox(str);Sleep(100);m_client.SendString(str);break;case N:str+=name;str+= ;str+=code;str+=CH;Sleep(100);m_client.SendString(str);break;void CCGameHallFrameView:dealMessage(char k)CString s;int i;switch(k)case M:name=;s.Format(你的用户名是:%s,name);MessageBox(s);pTable-flag=1;pTable-DrawTable();break;case O:if(protocol.right=1)for(int i=0;i4;i+)for(int j=0;jtableij.east=protocol.tableij.d0;pTable-tableij.south=protocol.tableij.d1;pTable-tableij.west=protocol.tableij.d2;pTable-tableij.north=protocol.tableij.d3;pTable-flag=1; pTable-DrawTable();elseMessageBox(用户名或密码错误!);break;case B:switch(protocol.direct)case 0:pTable-tableprotocol.desk/4protocol.desk%4.east=1;break;case 1:pTable-tableprotocol.desk/4protocol.desk%4.south=1;break;case 2:pTable-tableprotocol.desk/4protocol.desk%4.west=1;break;case 3:pTable-tableprotocol.desk/4protocol.desk%4.north=1;break;default:break;pTable-DrawTable();break;case P:switch(protocol.direct)case 0:pTable-tableprotocol.desk/4protocol.desk%4.east=0;break;case 1:pTable-tableprotocol.desk/4protocol.desk%4.south=0;break;case 2:pTable-tableprotocol.desk/4protocol.desk%4.west=0;break;case 3:pTable-tableprotocol.desk/4protocol.desk%4.north=0;break;default:break;pTable-dlg-user.IDprotocol.direct=0;pTable-dlg-GameEnd(protocol.direct);pTable-DrawTable();break;case Q:for(i=0;idlg-user.IDi=protocol.user.IDi;pTable-dlg-i=i;pTable-dlg-user.scorei=protocol.user.scorei;pTable-dlg-user.sexi=protocol.user.sexi;pTable-dlg-userMessage();break;case A:pTable-dlg-chatMessage(protocol.chat);break;case D:/pTable-tablepTable-dlg-desk/4pTable-dlg-desk%4.begin=TRUE;pTable-dlg-game.war_kind=protocol.war_kind;pTable-dlg-right=protocol.r;pTable-dlg-GameBegin();break;case F:/吃pTable-dlg-right=protocol.r;pTable-dlg-PlayResult(F,protocol.from,protocol.to);break;case G:/被吃pTable-dlg-right=protocol.r;pTable-dlg-PlayResult(G,protocol.from,protocol.to);break;case R:/碰pTable-dlg-right=protocol.r;pTable-dlg-PlayResult(R,protocol.from,protocol.to);break;case H:/炸pTable-dlg-right=protocol.r;pTable-dlg-PlayResult(H,protocol.from,protocol.to);break;case I:pTable-dlg-GameEnd(protocol.direct);break;游戏类class CGameDlg : public CDialogvoid CGameDlg:DrawChess(CDC *dc)/*CBitmap bitmap,right,left;int x,y,xr,xl,yr,yl;BITMAP BMap,br,bl; bitmap.LoadBitmap(IDB_SOUTHCHESS);right.LoadBitmap(IDB_RIGHTCHESS);left.LoadBitmap(IDB_LEFTCHESS);bitmap.GetBitmap(&BMap);left.GetBitmap(&bl);right.GetBitmap(&br);x=BMap.bmWidth;y=BMap.bmHeight;xr=br.bmWidth;yr=br.bmHeight;xl=bl.bmWidth;yl=bl.bmHeight;*/CDC dcMem;int dir,x,y,pos;dcMem.CreateCompatibleDC(dc); /创建与pDC兼容的设备上下文/dcMem.SelectObject(&left); /将位图对象选入设备上下文/dc-SetStretchBltMode(HALFTONE); /设置图缩放模式for(int i=0;i17;i+)for(int j=0;j0&boardij=0&i=6&j=6&i=0&j=11&i=6&j=6&i=11&j17)dir=0;if(boardijBitBlt(38+j*39,242+(i-6)*39,x/13,y,&dcMem,x/13*pos,0,SRCCOPY);break;case 1:dc-BitBlt(265+(j-6)*40,13+i*39,x/13,y,&dcMem,x/13*pos,0,SRCCOPY);break;case 2:dc-BitBlt(38+j*39,242+(i-6)*39,x/13,y,&dcMem,x/13*pos,0,SRCCOPY);break;case 3:dc-BitBlt(265+(j-6)*40,13+i*39,x/13,y,&dcMem,x/13*pos,0,SRCCOPY);break;default:break;dcMem.DeleteDC();int CGameDlg:FindImage(int k, int dir)int pos;switch(k)case 1:pos=8;break;case 2:pos=7;break;case 3:pos=6;break;case 4:pos=5;break;case 5:pos=4;break;case 6:pos=3;break;case 7:pos=2;break;case 8:pos=1;break;case 9:pos=10;break;case 10:pos=12;break;case 11:pos=11;break;case 12:case 16:case 17:case 18:pos=9;break;case 13:case 14:case 15:pos=0;break;default:break;return pos;CPoint CGameDlg:FindPos(int x, int y)CPoint pos;pos.x=-1;pos.y=-1;int i,j;j=(x-38)/39;i=(y-13)/39;if(i5&i5&j=0)pos.x=i;pos.y=j;return pos;void CGameDlg:DrawArrow(int i, int j,int k,CDC *dc)int x,y;x=j*39+30;y=i*39+10;CDC dcMem;dcMem.CreateCompatibleDC(dc); /创建与pDC兼容的设备上下文if(kBitBlt(x,y,BMap_arrow.bmWidth/9,BMap_arrow.bmHeight,&dcMem,BMap_arrow.bmWidth/9*k,0,MERGEPAINT);else if(k=8)dcMem.SelectObject(&bitmap_k1);dc-BitBlt(x,y,BMap_k1.bmWidth,BMap_k1.bmHeight,&dcMem,0,0,MERGEPAINT);else if(k=9)x+=5;y-=3;dcMem.SelectObject(&bitmap_k2);dc-BitBlt(x,y,BMap_k2.bmWidth,BMap_k2.bmHeight,&dcMem,0,0,MERGEPAINT);dcMem.DeleteDC();void CGameDlg:userMessage()int i,j;for(i=6;i11;i+)for(j=11;j17;j+)if(user.IDrotateDirect(0)=1&!(i=7&j=12)&!(i=7&j=14)&!(i=8&j=13)&!(i=9&j=12)&!(i=9&j=14)boardij=15;elseboardij=0;for(i=6;i11;i+)for(j=0;j6;j+)if(user.IDrotateDirect(2)=1&!(i=7&j=2)&!(i=7&j=4)&!(i=8&j=3)&!(i=9&j=2)&!(i=9&j=4)boardij=14;elseboardij=0;for(i=0;i6;i+)for(j=6;j11;j+)if(user.IDrotateDirect(3)=1&!(i=2&j=7)&!(i=2&j=9)&!(i=3&j=8)&!(i=4&j=7)&!(i=4&j=9)boardij=13;elseboardij=0;for(i=6;i11;i+)for(j=6;j0)boardij=0;m_GamerList.DeleteAllItems();for(i=0;iSetWindowText(m_strText);CEdit * output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);/随时跟踪滚动条的位置output-LineScroll(output-GetLineCount();void CGameDlg:OnUpdateMessage() / TODO: If this is a RICHEDIT control, the control will not/ send this notification unless you override the CDialog:OnInitDialog()/ function to send the EM_SETEVENTMASK message to the control/ with the ENM_UPDATE flag ORed into the lParam mask.CString in;CString s,t;GetDlgItem(IDC_MESSAGE)-GetWindowText(in);/输入框中只有回车键被按下,所以不发送回车键字符if(in.GetLength()SetWindowText();if(in.GetLength()2)m_strText+=in;/将输入的话显示到显示窗口中GetDlgItem(IDC_SHOWTEXT)-SetWindowText(m_strText);CEdit * output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);/随时跟踪滚动条的位置output-LineScroll(output-GetLineCount();s=char(20);s+=A;t.Format(%d ,desk);s+=t;s+=in;s+=char(20);pClient-SendString(s);BOOL CGameDlg:change(CPoint p1, CPoint p2)if(p1.x11|p2.x11|boardp1.xp1.y=0|boardp2.xp2.y=0)return FALSE;if(boardp1.xp1.y=11)if(p2.x15|p2.x=16&p2.y=7|p2.x=16&p2.y=9)return FALSE;if(boardp2.xp2.y=11)if(p1.x15|p1.x=16&p1.y=7|p1.x=16&p1.y=9)return FALSE;if(boardp1.xp1.y=10)if(p2.x=11|p2.x=16&p2.y=7|p2.x=16&p2.y=9)return FALSE;if(boardp2.xp2.y=10)if(p1.x=11|p1.x=16&p1.y=7|p1.x=16&p1.y=9)return FALSE;if(boardp1.xp1.y=12)if(!(p2.x=16&p2.y=7|p2.x=16&p2.y=9)return FALSE;if(boardp2.xp2.y=12)if(!(p1.x=16&p1.y=7|p1.x=16&p1.y=9)return FALSE;int sum;sum=boardp1.xp1.y;boardp1.xp1.y=boardp2.xp2.y;boardp2.xp2.y=sum;return TRUE;void CGameDlg:MessageWcdd()CString s,t;s=char(20);s+=C;t.Format(%d ,desk);s+=t;t.Format(%d ,direct);s+=t;int i,j;for(i=11;i17;i+)for(j=6;jSendString(s);void CGameDlg:GameBegin()music.PlayMusic(1);for(int i=0;i17;i+)for(int j=0;jSendString(s);void CGameDlg:PlayResult(c
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。