1、淮阴师范学院毕业论文(设计)毕业设计说明书学生姓名学 号学院 计算机科学与技术学院专 业软件工程题 目基于MFC的对战象棋设计与实现指导教师 (姓 名) (专业技术职称/学位)38毕业论文独创性声明本人郑重声明:本论文是我个人在导师指导下进行的研究工作及取得的研究成果。本论文除引文外所有实验、数据和有关材料均是真实的。尽我所知,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发表或撰写过的研究成果。其他同志对本研究所做的任何贡献均已在论文中作了明确的说明并表示了谢意。作者签名: 日 期: 摘 要:中国象棋是我国历史悠久的智力对战游戏,发展至今已有数千年的历史,是中华民族智慧的结晶。然
2、而,传统象棋存在着棋盘单一、棋子收拾繁琐、下棋场地单一、无法及时找到对弈玩家几大弊端。随着计算机技术的发展,电子版象棋游戏的诞生,很好的解决了这些问题。 本设计正是开发这样一款电子象棋游戏,它采用MFC文档视图体系结构和VisualC+开发工具,实现了具有背景棋盘和棋子种类的变换,走棋,悔棋,还原和网络对弈功能。本设计还进行了画面闪烁消除,视觉效果更加人性化,且鼠标操作,简单易用,无须安装,即开即用。 关键词:中国象棋,MFC文档视图,Visual C+,网络对弈,消除闪烁,即开即用Abstract:Chinese Chess is our long history of intellectu
3、al battle game, the development has several thousand years of history, is the crystallization of the wisdom of the Chinese nation. However, the traditional chess there is a single board, the pieces pack cumbersome, chess venues single, not been able to find several major drawbacks of the chess playe
4、rs. With the development of computer technology, the electronic version of the birth of a chess game, a good solution to these problems.The design is the development of an electronic chess game, which uses MFC document view architecture and Visual C + + development tools, background board and pieces
5、 kind of transformation, playing chess, undo, restore, and network chess function. This design also flickering eliminate, visual effects, more human, mouse operation, easy to use, no need to install.Keywords:Chinese chess, MFC document view, Visual C+, network game, eliminate flicker, instant availa
6、ble目 录1 绪论41.1 课题背景41.2 象棋简介41.3 MFC及相关技术42 概要设计42.1 设计思路分析42.2 主要功能42.3 软件信息42.4 流程图43 程序详细设计说明43.1 界面设计43.2 数据结构43.3 棋子走法43.3.1 車43.3.2 馬43.3.3 相(象)43.3.4 仕(士)43.3.5 帅(将)43.3.6 炮(砲)43.3.7 兵(卒)43.4 功能43.4.1 走棋43.4.2 悔棋43.4.3 还原43.4.4 认输43.4.5 摆棋43.5 网络43.6 关键技术43.6.1 遮罩技术43.6.2 双缓冲技术44 总结和进一步的研究工作4
7、结束语4参 考 文 献4致 谢41 绪论1.1 课题背景随着时代的进步,电子技术日新月异的发展,单纯的户外实体游戏已经无法满足人们的需求,于是电子游戏诞生了,它创造出的虚拟游戏环境,帮助人们摆脱实体的束缚,更增添了游戏的趣味性。计算机的发明,无疑使电子游戏又多了一个新的载体,带动其不断地创新、发展。电脑游戏行业经过二十余年的发展,已成为与音乐、影视等并驾齐驱的全球最重要娱乐行业之一。时下,与角色扮演类、即时战略类游戏相比,棋牌类游戏这种上手快、游戏时间短的传统游戏方式,仍在广大群众中占有举足轻重的地位。其中方便、快捷、操作简单的棋类游戏,更是占主要位置。作为中华民族悠久文化的代表之一,中国象棋
8、不仅源远流长,而且基础广泛,作为一项智力运动,中国象棋开始走向世界。为了方便其更好的推广,并且为了摆脱传统棋盘、棋子、场地的束缚,网络版象棋备受青睐,这也是本款象棋游戏开发的意义所在。相信未来几年,象棋这一中国国粹在各个领域将得以推广,产生巨大影响。 1.2 象棋简介中国象棋历史悠久。楚辞 招魂中有“蓖蔽象棋,有六簿些;分曹并进,遒相迫些;成枭而牟,呼五白些。”。说苑载:雍门子周以琴见 孟尝 君,说:“足下千乘之君也, 燕则斗象棋而舞郑女。”由此可见,远在战国时代,象棋已在贵族阶层中流行开来了。象棋属于二人对抗性游戏的一种,暗棋阁也是其中一种传统玩法,由于用具简单,趣味性强,成为流行极为广泛的
9、棋艺活动。象棋是我国正式开展的78个体育运动项目之一,为促进该项目在世界范围内的普及和推广,已将“中国象棋”项目名称更改为“象棋”。此外,高材质的象棋也具有收藏价值,如:高档木材、玉石等为材料的象棋。更有文人墨客为象棋谱写了诗篇,使象棋更具有一种文化色彩。1.2.1 象棋棋盘棋子活动的场所,叫作“棋盘”。在长方形的平面上,共有九条平行的竖线和十条平行的横线,共有九十个交叉点。棋盘两端的中间,也就是第四条到第六条竖线之间的正方形部位,有斜交叉线“米”字方格的地方,叫作“九宫”,象征着中军帐,是将和帅的驻扎地。 整个棋盘以“楚河汉界”分为相等的两部分。为了比赛记录和学习棋谱的统一,现在规则规定:从
10、右至左的九条竖线,用中文数字一至九来表示红方,用阿拉伯数字1至9来表示黑方。己方的棋子始终使用己方的线路编号,无论棋子是否“过河”。 1.2.2 象棋棋子象棋是一种双方对弈的竞技项目。棋子共有红黑16个,共32个棋子。棋子种类说明如下表1-1:表1-1 棋子种类红方名称黑方名称每方棋子数活动范围帅将1本方九宫内仕士2本方九宫内(实际5个棋位)相象2本方区域内(实际7个棋位)马马2全盘任意位置车车2全盘任意位置炮炮2全盘任意位置兵卒5起始位置及前进一步的位置,敌方所有棋位将与帅;士与仕;象与相;卒与兵的功能实际上完全相同,仅是为了区分黑红双方。帅(将)是棋中的首脑,也是战术核心。它只能在本方九宫
11、之内活动,可上下左右沿着横线或者竖线移动一格。帅与将不能在同一直线上直接对面,否则走方判负。这个也就是判定函数ShuaiCanTo()实现的功能的依据。 仕(士)是将(帅)的贴身保镖,主要任务是防守,它也只能在九宫内走动,且只能斜走,不先后左右移动。相(象)的主要作用也是防守,保护自己的帅(将)。它的走法是每次沿对角线走两格,俗称“象飞田”。相(象)的活动范围限于河界以内的本方阵地,不能过河,实际是7个特殊棋位,且若它走的田字中央有一个棋子,不管是对方还是本方棋子,都不能走,俗称“塞象眼”。 车在象棋中威力最猛,只要起始位置和目的位置中间没有其他棋子,它就可以到达它横竖线所在的任何地方。俗称“
12、一车十子寒”。 炮不吃子时,移动走法与车完全一样。但当吃子时,它和目标棋子中间必须有一个且仅此一个棋子(无论己方或对方棋子)。炮是象棋里面唯一一个可以越子的棋种,威力也很大。 马是先直后斜,即先直着走一格,然后再斜着走一个对角线,俗称“马走日”。马一个可到周围八个点,故有“八面威风”之说。但如果在要去的方向的第一步有别的棋子挡住,马就无法走过去,俗称“蹩马腿”和“塞象眼”类似。 兵(卒)不能后退且只能一步一步走,未过河前,只能向前。过河以后,允许左右移动。虽过河后只能一步一步走,但兵(卒)的威力也大大增强,故有“过河的卒子顶半个车”之说。 1.2.3 术语8(1) “马走日字,象飞田.车走直路
13、,炮翻山.士走斜路护将边.小卒子一去不回还. 车走直路马踏斜,相飞田子炮打隔,卒子过河了不得。”(2)“马后炮”:泛指炮在马后,以马限制对方将帅的退路,兼以炮向对方叫将。 (3)“天地炮”:一炮从中路牵制对方中士中象,另一炮从底线牵制对方底士底象。 (4)“铁门栓”:以炮镇中路限制对方士象的活动,兼以车或兵(卒)守着对方的将(帅)门。 (5)“夹车炮”:车炮或车双炮前后互相配合的一种战术。 (6)“炮碾丹沙”:车炮在底线成将, 从而杀去障碍 (主要是士象)成杀势。 (7)“车炮抽杀”:泛指炮在车后时,一面跳炮吃子,一面露车叫将,令对方顾此失彼的一种战术。 (8)“海底捞月”:车炮或车兵在对方底
14、线逼使对方将帅离开中路的一种战术。 (9)“两头蛇”:把三路兵和七路兵挺起的阵式。 1.3 MFC及相关技术MFC:微软基础类(Microsoft Foundation Classes),C+是一种应用程序框架,随微软Visual C+开发工具一起发布。该类库提供一组通用的可重用的类库供开发人员使用,大部分类均从CObject 直接或间接派生,只有少部分类例外。MFC应用程序的总体结构通常由开发人员从MFC类派生的几个类和一个CWinApp类对象(应用程序对象)组成。MFC 提供了MFC AppWizard 自动生成框架。Windows 应用程序中,MFC 的主包含文件为Afxwin.h。此外
15、MFC的部分类为MFC/ATL 通用,可以在Win32 应用程序中单独包含并使用这些类。1.3.1 单文档程序1.应用类及全局对象(CChess_mApp)应用类封装了Windows应用的初始化,运行以及终止的全过程。对于每一个基于框架的应用,它必须有一个且只能有一个派生于CWinApp的类对象。这个对象是全局对象,因此它在创建任何窗口前首先被构造。类CWinApp提供了几个关键的可重载的虚成员函数,他们是InitInstance,Run,ExitInstance以及OnIdle等。而且,在程序中可以随时调用全局函数AfxGetApp,以便获得CWinApp类对象的指针。2.文档类(CChes
16、s_mDoc)文档类实际上是一种数据结构,该类实现了对这种结构的封装以利于管理,通常,它不但包含应用中所需的数据,而且也包含了处理这些数据的方法,另外,文档类还可以为应用提供与其存储的数据相关的服务。3.视图类(CChess_mView)该类占有框架窗口的客户区,主要负责显示文档数据,也为文档对象和用户之间提供了用以交互的可视接口,另外,也完成了与文档打印相关的操作,通常,一般的绘制操作都是在该类中完成,因此有时也称视图类窗口为“绘制窗口”。4.框架类(CMainFrame)框架类表示应用程序的主框架窗口,其主要作用是响应标准的窗口消息,不过,它通常先将消息按照一定的次序传递给视图类以及文档类
17、等其他命令处理类,另外,它还为视图类提供可视化的边框,同时也包括标题栏,一些标准的窗口组件等。5.“关于”对话框类(CAboutDlg)该类封装了用于显示软件版本,版权等相关信息的“关于”对话框,通常不需要对它进行任何的编程。而只需要使用对话框资源编辑器对对话框模板进行简单的编辑即可。1.3.2 GDI绘图GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。在Windows操作系统下,绝大多数具备图形的的应用程序都离不开GDI,他们利用GDI所提供的众多函数可以方便地在屏幕,
18、打印机及其他输出设备上输出图形、文本等。GDI的出现时程序员无需关心硬件设备及设备驱动,就可以将应用程序的输出转化为硬件设备上的输出。这实现了程序开发者与硬件设备的隔离,大大方便了开发工作。想要在屏幕或者其他输出设备上输出图形或者文字,就必须先获得一个称为设备描述表(DC:Device Context)的对象的句柄,以它为参考,调用各种GDI函数来实现各种文字或图形的输出。设备描述表是GDI内部保存数据的一种数据结构,此结构中的属性内容与特定的输出设备(显示器、打印机等)相关,属性定义了GDI函数的工作细节。属性包括文字的颜色及x坐标和y坐标映射到窗体显示区域的方式等。一旦获得设备描述表的句柄
19、,系统就是使用默认的属性值填充设备描述表结构。如果有必要,可以使用一些GDI函数获得和改变设备描述表中的属性值。绘图结束后必须释放设备描述表句柄。GDI函数大致可分类为:设备上下文函数(如GetDC、CreateDC、DeleteDC)、 画线函数(如LineTo、Polyline、Arc)、填充画图函数(如Ellipse、FillRect、Pie)、画图属性函数(如SetBkColor、SetBkMode、SetTextColor)、文本、字体函数(如TextOut、GetFontData)、位图函数(如SetPixel、BitBlt、StretchBlt)、坐标函数(如DPtoLP、LPt
20、oDP、ScreenToClient、ClientToScreen)、映射函数(如SetMapMode、SetWindowExtEx、SetViewportExtEx)、元文件函数(如PlayMetaFile、SetWinMetaFileBits)、区域函数(如FillRgn、FrameRgn、InvertRgn)、路径函数(如BeginPath、EndPath、StrokeAndFillPath)、裁剪函数(如SelectClipRgn、SelectClipPath)等。1.3.3 消息机制MFC传输的消息有三种类型:命令消息,控件通知和窗口消息。命令消息一般与用户请求有关,当用户单击一个菜
21、单项时,命令消息产生,并发送给能处理这个消息的类对象(如编辑文本等)。控件消息在某些重要事件发送时,由控件窗口发送给父窗体处理,如打开一个对话框。窗口消息(Window Message)一般与窗口的内部运作有关,如创建窗口消息W M PA I N T和绘制窗口W M C R E AT E等。通常,消息是从系统发送到窗口,或从窗口发送到窗口。每个窗口使用窗口进程来处理发送给它的消息。系统或应用程序有两种传输消息的方法:发送消息或寄送消息。鼠标和键盘消息一般是寄送消息,而所有其他消息通常都是发送消息。发送消息时,直接调用窗口的窗口进程,通信是即时的,直到窗口进程为调用函数返回一个结果时,应用程序才
22、能继续。寄送消息时,把消息发送到拥有那个窗口的应用程序的消息队列中。当应用程序空闲时,它会搜索消息队列,并处理优先级较高的消息,然后从队列中删除它,并把处理结果发送给既定窗口。所以通信可能延迟。在消息队列中,寄送的消息接受特殊的鼠标和键盘处理。通常,应该尽量发送一个消息,除非想把动作延迟到所有鼠标和键盘消息被处理之后。2 概要设计2.1 设计思路分析本程序采用MVC模式,将棋子信息与显示分离,统一由control控制。棋盘用9*10的数组map存储(013表示各个棋子,14表为空),存储用于判断当前位置为何棋子或者空。32个棋子由一个统一的棋子型CChess数组存储,统一管理显示。每个棋子包含
23、了自身的type,name,及其在棋盘中的位置x,y。棋子走法是利用鼠标的消息处理函数,获得棋子种类,当前坐标和下一步坐标,共五个信息,再利用规定的CanGoTo()函数判断能否到达。若能到达,则把当前棋子的坐标改为下一步坐标,并把棋盘中当前位置的map改为空,即表示无棋子。如果下一步坐标的位置上有棋子,则将该棋子的type改为15,这样绘图时就不会显示该棋子的位图。因为棋子位图周围有白色边框,通过“遮罩技术”可以消除边框,实现棋子透明覆在棋盘上,更具美感。利用“内存DC双缓冲技术”消除闪烁,将棋盘和棋子信息一次性显示,并实现棋子黏在鼠标上,动态移动。网络部分,继承MFC中的CAsyncSoc
24、ket和CSocket进行开发。Socket编程分为两种:面向连接协议网络通信编程和面向无连接的网络通信编程。本设计采用连接协议的Socket编程模型,保证网络上传输的数据及时、正确的到达。2.2 主要功能通过计算机的鼠标键盘操作操作界面,必须按照象棋的规则进行对弈,如果在对弈过程中,一方出招错误,电脑会予以简单提示,并无视错误操作。对弈过程中只能按照电脑预订顺序,即红先黑后的顺序依次出招,指导一方胜出,电脑显示哪方胜出为止。 1) 可以采用鼠标操作进行对弈;2) 可以实现走棋、悔棋、还原、认输功能;3) 可以满足两人局域网内对弈;4) 可以在任意时间重新开始游戏;5) 可以进行简单错误判断,
25、并直接返回到前一步棋子状态;6) 可以进行背景棋盘和棋子种类的变换;7) 可以实现自由设置棋谱(怪棋);8) 可以实现棋子黏在鼠标上移动,增加美感2.3 软件信息1) 软件名称:基于MFC的局域网内对战象棋设计与实现2) 开发平台:Microsoft Visual C+ 6.03) 用户:象棋爱好者4) 本设计在各个方面均具有可行性,方便易用,无需安装即可使用2.4 流程图(1)游戏交互图,如图2-1所示游戏界面网络游戏内核图2-1 游戏交互图(2)程序流程图首先,选择是否建立主机,否则为客户机。若建立主机,则建立一个端口,用于和客户机的交互连接,然后等待知道有客户机连上。客户机建立,则选择主
26、机的ip地址和端口。游戏双方先后点击开始,开始游戏。红方、黑方在到自己状态时,可以移动自己的棋子,悔棋,还原,认输等等。走棋,点击鼠标左键选中棋子,移动,放到想到达的地方,系统调用CanGoTo函数,判断是否可到,若可到,则棋子放到目的地,否则返回棋子原来的地方能够。走棋成功后,发送消息给对方,对方接收消息后,进行相应的操作。进行若干步之后,若帅或者将被吃掉,则判定胜负。具体流程,见图2-2程序流程图。N开始结束等待直到收到消息调用FetchMsg处理相应的信息如果帅编号属性不是帅等待直到收到消息调用FetchMsg处理相应的信息如果将编号属性不是将Y输入主机IP地址和端口号Nm_State=
27、1建立主机建立端口m_State=0走棋,悔棋,还原 操作SendMsg相应消息YNY(m_State+1)%2YYNN图2-2程序流程图3 程序详细设计说明3.1 界面设计本程序界面简单明了,包括棋盘显示,listbox,开始、悔棋、还原、认输四个按钮,还有用于聊天的edit和发送按钮。菜单栏包括文件,控制,背景,帮助。其中listbox 是记录每步棋子走棋的信息和聊天信息,也是实现悔棋功能的一个重要存储器。它是一个栈,可以记录,删除,提取每步棋子的信息。悔棋操作可以从中得到相应的数据来实现悔棋功能。文件内有新游戏、摆棋操作,控制内有悔棋、还原、认输操作,背景内有棋盘和棋子的切换操作。主界面
28、,如图3-1所示图3-1 主界面3.1.1 棋盘、棋子的位图载入与切换(1)棋盘、棋子的位图载入本设计实现了棋盘和棋子的自由无限制转换,采用了外部图片载入的方式,加载的位图,棋盘棋子一起加载,没有自己繁琐的自绘棋盘棋子过程。本设计有6种棋盘,3种棋子可以搭配。若程序在开始时就全部加载,会浪费大量内存,因为游戏过程中只需要一副棋盘棋子,且不利于更多棋盘和棋子种类的更新,也不利于后期维护。故本程序采用外部图片载入的方式,载入棋盘棋子,每次切换调用SetBoardandPiece(CString strBoard , CString strPiece)重新对棋盘棋子的位图进行赋值。strBoard,
29、strPiece代表棋盘,棋子的存放文件夹相对物理地址。HBITMAP CChess_mView:LoadFileBmp(CString filePath)Return(HBITMAP)LoadImage(AfxGetInstanceHandle(),filePath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);void CChess_mView:SetBoardandPiece(CString strBoard, CString strPiece )/0红兵 1红袍 2红车 3红马 4红相 5红士 6红帅 7黑兵8 黑袍 9黑车10黑马11黑象12黑士13黑将 大于1
30、3不是棋子ChessList13 = LoadFileBmp(strPiece + BK.BMP);ChessList12 = LoadFileBmp(strPiece + BA.BMP);ChessList11 = LoadFileBmp(strPiece + BB.BMP);ChessList10 = LoadFileBmp(strPiece + BN.BMP);ChessList9 = LoadFileBmp(strPiece + BR.BMP);ChessList8 = LoadFileBmp(strPiece + BC.BMP);ChessList7 = LoadFileBmp(st
31、rPiece + BP.BMP);ChessList6 = LoadFileBmp(strPiece + RK.BMP);ChessList5 = LoadFileBmp(strPiece + RA.BMP);ChessList4 = LoadFileBmp(strPiece + RB.BMP);ChessList3 = LoadFileBmp(strPiece + RN.BMP);ChessList2 = LoadFileBmp(strPiece + RR.BMP);ChessList1 = LoadFileBmp(strPiece + RC.BMP);ChessList0 = LoadFi
32、leBmp(strPiece + RP.BMP);ChessList14 = LoadFileBmp(strPiece + SEL.BMP);/光标位图ChessList15 = LoadFileBmp(strBoard); ChessList16 = LoadFileBmp(strPiece + mask.bmp); /用于遮罩技术(见关键技术)(2)棋盘、棋子的切换当点击菜单栏背景的棋盘或者棋子,可以选择不同的棋盘和棋子。减少玩家的视觉审美疲劳。每按一个按钮,其实是改变了存放棋盘或棋子的函数SetBoardandPiece(CString strBoard , CString strPie
33、ce)中的strBoard 或strPiece,即棋谱棋子的存放文件夹相对物理地址,完成了棋盘棋子的种类切换,并用Invalidate(FALSE)及时更新显示。例如点击棋盘的水滴棋盘void CChess_mView:OnDrop() m_strBoard = resimagesdrops.bmp;SetBoardandPiece(resimagesdrops.bmp,m_strPiece);Invalidate(FALSE);运行图,如图3-1所示:图3-2 棋盘、棋子的切换3.1.2 光标生成双方局域网内对战,消息传递过来,执行操作了,但是我不能马上知道对方动了哪个棋子;可能已经动了,但
34、是我不知道,浪费时间。光标的生成,可以起到提醒对方我已经走过棋了,也利于在我方还没有出招之前始终知道对方的上一步是怎么走的,只有在我方出招之后对方的操作痕迹才可能被销毁,这样的设计增强了棋谱的可读性,也减轻了玩家的记忆负担。光标在棋盘载入的时候就一起载入了ChessList14 = LoadFileBmp(strPiece + SEL.BMP);在选中棋子时,即鼠标左键按下后,鼠标move的时候就把光标位图贴到选中子的周围,鼠标up再把位图贴到up的位置上。具体代码见鼠标的消息处理函数,OnLButtonDown(),OnMouseMove(),OnLButtonUp()运行结果,如图3-2所
35、示:图3-3 光标生成3.2 数据结构本设计主要包含CChess,CChess_mView,Cmanager,CNet,CNetControl四个类。CNet,CNetControl两个类用于网络部分,后面网络功能部分再详解。(1)CChess类是棋子类,存储了棋子的相关属性信息。class CChess public:int type;/0红兵 1红袍 2红车 3红马 4红相 5红士 6红帅 7黑兵8 黑袍 9黑车10黑马11黑象12黑士13黑将 大于13不是棋子CString name;int x;int y;Type即棋子的类别用于判定属于哪种棋子。name棋子的名字,例如“炮”。x,y
36、是棋子在逻辑坐标轴上的坐标。(2)Cmanager类是棋子控制类,是游戏内核。class CManager public:CChess nChessinfo32;/记录32个棋子的信息int map910;/记录棋盘上的信息int PlayerAc;/用来判断是哪个棋手void InitData();/数据初始化int m_State;/ 游戏状态 -1、游戏等待中,等待开始 0、游戏中 红方走棋 1、游戏中 黑方走棋int top; /记录游戏步数int Marry5008; /记录 前一个的标号,type,x,y 后一个的标号,type,x,y 共八个信息int MarryTop; /记录
37、游戏步数,为了还原时能够判断int count;/记录listbox的步数 包括游戏步奏和聊天记录public:int Search(int x,int y);/找是第几颗棋子 共32颗(031),若不存在棋子,返回32bool CanGoTo(int Old_Point_x,int Old_Point_y,int Now_Point_x,int Now_Point_y,int chesstype);/判断棋子能否到达,是每个棋子的走法判断bool ShuaiCanGoTo(int Old_Point_x,int Old_Point_y,int Now_Point_x,int Now_Poin
38、t_y,int chesstype); /是关于将帅问题的能否到达判断,将帅不共线 ;(3)CChess_mView 类是程序的显示类,也包含少部分的棋子控制操作功能和很多消息响应函数,由于篇幅问题没有全部显示。class CChess_mView : public CViewprotected:CChess_mView();DECLARE_DYNCREATE(CChess_mView)/ Attributespublic:CChess_mDoc* GetDocument();CNetControl *m_pControl; /网络控制显示int choosed;/记录前一个棋子是第几个棋子i
39、nt OldType;/记录前一个棋子的类型int OldX;/记录前一个棋子的横坐标int OldY;/记录前一个棋子的纵坐标/用于右键功能int Rchoosed;/记录当前一个棋子是第几个棋子 int ROldX;/记录前一个棋子的横坐标int ROldY;/记录前一个棋子的纵坐标/变量定义HBITMAP ChessList17;/位图数组CString m_strPiece;/棋子根目录CString m_strBoard;/棋盘根目录int m_nBoardIndex,m_nPieceIndex; /背景设置选择/定义画图用CDCCDC Background;/背景句柄CDC Che
40、ssAll; /最终刷新句柄CDC Buffer;/缓冲句柄 用于双缓冲CListBox m_listbox; /用于记录每步棋子走棋的信息和聊天信息CButton m_ok; /开始按钮CButton m_goback; /悔棋按钮CButton m_huanyuan; /还原按钮CButton m_renshu; /认输按钮CButton m_send;/聊天发送按钮CEdit m_edit;/用于聊天的editint down_move;/用于鼠标按下时的控制int move_up; /用于鼠标弹上时的控制int goback_huanyuan; /用于只有在有悔棋额情况下才能还原的控制
41、/ Operationspublic:void OnOk();/开始void OnGoBack();/悔棋void OnHuanYuan();/还原void OnRenShu();/认输void OnSend();/发送聊天信息/函数定义void InitData();/初始化void NewGame();/新游戏void TextOutTop();/提示现在出牌void PrintAll(); /把界面存储于buffer中void PrintAllMsg(); /用于网络刷新和整体刷新void PrintAllDMsg();/用于网络动棋子的时候整体刷新HBITMAP LoadFileBmp
42、(CString filePath); /载入位图void SetBoardandPiece(CString strBoard,CString strPiece);/给棋盘棋子赋值/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CChess_mView)public:virtual void OnDraw(CDC* pDC); / overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protecte
43、d:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);/AFX_VIRTUAL/ Implementationpublic:virtual CChess_mView();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext
44、& dc) const;#endifprotected:/AFX_MSG(CChess_mView) .(省略)/AFX_MSGDECLARE_MESSAGE_MAP();3.3 棋子走法棋子走棋规则在“1.2.2 象棋棋子”已有介绍,这里不再累述。这里主要介绍各个棋子的程序具体实现。具体见CanGoTo(int Old_Point_x,int Old_Point_y,int Now_Point_x,int Now_Point_y,int chesstype)和ShuaiCanGoTo(int Old_Point_x,int Old_Point_y,int Now_Point_x,int No
45、w_Point_y,int chesstype)函数。首先,不管是什么棋子,都不能吃自己一方的棋子。if (mapOld_Point_xOld_Point_y/7=mapNow_Point_xNow_Point_y/7) return false;3.3.1 車车只要中间没有棋子阻碍,可以到达它横竖线所在的任何地方。所以只需判断始末位置为端点的线段上的棋子个数,即判断map不为空的个数。若只有一个,则表示目标位置没有棋子,可以直达。若有两个,且目标位置不为空,则表示吃子,可达。/车if (9=chesstype|2=chesstype)/同一行if (Old_Point_y=Now_Point_y)int maxcol=(Old_Point_xNow_Point_x)?Old_Point_x:Now_Point_x;int mincol