资源描述
毕 业 论 文 基于C+语言的智力游戏的设计 四川师范大学经济职业学院学院(系): 计算机科学与技术 专业班级 : 软件工程2 学生姓名 : 指导老师 : 内容摘要: C+语言是一种面向对象的语言,尽管在当前,可视化语言发展迅速,普及很快,但C+语言作为一种基础的语言,它的有时依然存在,甚至有时它是不可替代的,特别是和硬件接口技术相联系的软件。五子棋游戏是一种简单大众的游戏,自从计算机实现以来,深受广大电脑玩家的喜爱,现在流行的五子棋游戏软件大多缺乏美观的界面,和容易的操作方法,电脑的AI值也不是很高。本文通过C+语言在计算机图形方面的编程,设计了五子棋游戏软件,使该软件具有美观友好的截面,在人机对弈时,使电脑具有较高的智商。本游戏是以C+语言作为开发工具,采用搜索算法设计最优落子点开发的游戏软件。本文详细地介绍了五子棋游戏软件设计的全过程,描述了该软件的功能,以及和其它五子棋程序的一些比较。关键词:C+语言 面向对象语言 最优落子算法 Disigned of Puzzle based on C+ LanguageAbstract: The C+ language is an object oriedted language, although in the current visualization language rapidly, and spread quickly, but the C+ language as a basis for language, its advantages still exist, and sometimes it is irreplaceable, particularly hardware and software interfaces are linked. Gobang game is a simple and popular game, since the computer to achieve, by the love of computer players, but now most popular game soft gobang lack aesthetic interface, and easy method of operation, the value of the computer AI is not high. The adoption of the C+ programming language in computer graphics, designed gobang game software to enable the software with a beautiful and friendly interface in both game, the computer has a higher IQ. The game is based on C+ language, using searching algorrithm to design best gobang. The detailed presentation of the whole process of gobang game software design, describes the software functions and procedures and other gobang other gobang some more.Keywords: C+ language object oriedted language best algorithm 目 录前言5一、五子棋介绍及其开发环境5(一)五子棋介绍6(二)开发背景6(三)开发环境及运行环境61开发环境62运行环境6二、软件结构7(一)棋盘类7(二)游戏模式类7三、棋盘类Ctable8(一)主要成员变量说明8(二)主要成员函数说明91.套接字的回调处理Accept、Connect、Receive92.清空棋盘Clear93.绘制棋子Draw94.左键消息OnLButtonUp105.绘制棋盘OnPaint106.对方落子完毕Over107.设置游戏模式SetGameMode108.胜负的判断Win11四、游戏模式类CGame11(一)主要成员变量说明121.棋盘指针m_pTable122.落子步骤m_StepList12(二)主要成员函数说明121.悔棋操作Back122.初始化操作Init123.接收来自对方的消息ReceiveMsg134.发送落子消息SendStep135.胜利后的处理Win13五、消息机制13(一)消息机制的架构13(二)各种消息说明14六、主要算法17(一)判断胜负17(二)人机对弈算法201.获胜组合202.落子后处理213.查找棋盘空位214.落子打分225.防守策略246.选取最佳落子25七、补充说明26八、结束语26参考文献27基于C+语言的智力游戏的设计前言五子棋是人们喜欢的一种棋类游戏,近来,随着计算机的快速发展,以计算机作为对战平台,各种棋类游戏如雨后春笋般纷纷冒出,使得那些喜爱下棋,有常常苦于没有对手的棋迷们能随时过足棋瘾,而且这类软件个个水平颇高,大有与人脑分庭抗礼之势。其中战胜过国际象棋世界冠军卡斯帕罗夫的“深蓝”便是最具说服力的代表。当我们与电脑对战对时,您知道这些软件是怎样像人脑一样进行思考的吗?总的来说(我们假定您熟悉五子棋的基本规则),要让电脑知道该在哪一点下子,就要根据盘面的形式,为每一可能落子点计算其重要程度,也就是当这子落下后会形成什么模型,然后通览全盘选出最重要的一点,这便是最基本的算法。当然,仅靠当前盘面进行判断是远远不够的,这样下棋很容易掉进玩家设下的陷阱,因为它没有考虑以后的变化。所以在此基础上我们需要使用好的算法是电脑能预测出今后几步的各种走法,以便做出最佳选择,这也是我们下棋时常说的“想了几步”。怎样才能达到这个程度呢?这是本文所要讨论的主要问题。作为一个五子棋游戏爱好者,在使用了众多的五子棋游戏软件后,发现当今大多数五子棋游戏软件中电脑的AI值不是很高,难与人脑抗衡,这是基于以上的最基本算法扩展而出的电脑最优落子算法不够优秀而造成的。本人使用C+语言作为开发工具,在吸收别人所编的五子棋游戏软件的基础上,再融入自己的创新思想(最优落子算法的改进),编写了这个五子棋游戏,软件实现了人机对弈和双人对弈的功能,游戏软件界面美观,操作容易,电脑的AI值也较高。一、五子棋介绍及其开发环境(一)五子棋介绍五子棋起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。(二)开发背景当前网络上流传的五子棋游戏功能并不尽善尽美,其中最主要的问题就是人机对战和网络对战不能够一起实现,所以我决定开发一个既能够人机对战,又能够进行网络对战的五子棋系统。(三)开发环境及运行环境1开发环境l Intel Pentium 4 2.0GHz,512M内存,80G硬盘l Microsoft Windows 2000 Professionall Microsoft Visual C+ 6.0l Microsoft Developer Network for Visual Studio.NET 2003l Visual Assist X 10.1.1301.02运行环境l Intel Pentium 2及以上处理器,32M以上内存,4G以上硬盘l Microsoft Windows 9X/NT操作系统l 800*600或以上的屏幕分辨率 二、软件结构考虑到整个的下棋过程(无论对方是电脑抑或其他网络玩家)可以分为:己方落子、等待对方落子、对方落子、设置己方棋盘数据这一系列过程,因此一人游戏类、二人游戏类和棋盘类之间的关系参考了AbstractFactory(抽象工厂)模式,以实现对两个不同模块进行一般化的控制。软件的总体架构如图1所示。(一)棋盘类整个架构的核心部分,类名为CTable。封装了棋盘的各种可能用到的功能,如保存棋盘数据、初始化、判断胜负等。用户操作主界面,主界面与CTable进行交互来完成对游戏的操作。(二)游戏模式类用来管理人机对弈/网络对弈两种游戏模式,类名为CGame。CGame是一个抽象类,经由它派生出一人游戏类COneGame和网络游戏类CTwoGame,如图2所示。图1 软件架构图2 CGame类派生关系这样,CTable类就可以通过一个CGame类的指针,在游戏初始化的时候根据具体游戏模式的要求实例化COneGame或CTwoGame类的对象;然后利用多态性,使用CGame类提供的公有接口就可以完成不同游戏模式下的不同功能了。三、棋盘类Ctable(一)主要成员变量说明l 网络连接标志m_bConnected用来表示当前网络连接的情况,在网络对弈游戏模式下客户端连接服务器的时候用来判断是否连接成功;事实上,它也是区分当前游戏模式的唯一标志。l 棋盘等待标志m_bWait与m_bOldWait 由于在玩家落子后需要等待对方落子,m_bWait标志就用来标识棋盘的等待状态。当m_bWait为TRUE时,是不允许玩家落子的。在网络对弈模式下,玩家之间需要互相发送诸如悔棋、和棋这一类的请求消息,在发送请求后等待对方回应时,也是不允许落子的,所以需要将m_bWait标志置为TRUE。在收到对方回应后,需要恢复原有的棋盘等待状态,所以需要另外一个变量在发送请求之前保存棋盘的等待状态做恢复之用,也就是m_bOldWait。等待标志的设置,由成员函数SetWait和RestoreWait完成。l 网络套接字m_sock和m_conn在网络对弈游戏模式下,需要用到这两个套接字对象。其中m_sock对象用于做服务器时的监听之用,m_conn用于网络连接的传输。l 棋盘数据m_data这是一个15*15的二位数组,用来保存当前棋盘的落子数据。其中对于每个成员来说,0表示落黑子,1表示落白子,-1表示无子。l 游戏模式指针m_pGame这个CGame类的对象指针是CTable类的核心内容。它所指向的对象实体决定了CTable在执行一件事情时候的不同行为,具体的内容请参见“游戏模式”一节。(二)主要成员函数说明1.套接字的回调处理Accept、Connect、Receive本程序的套接字派生自MFC的CAsyncSocket类6,CTable的这三个成员函数就分别提供了对套接字7回调事件OnAccept、OnConnect、OnReceive的实际处理,其中尤以Receive成员函数重要,它之中包含了对所有网络消息(参见“消息机制”一节)的分发处理。2.清空棋盘Clear在每一局游戏开始的时候都需要调用这个函数将棋盘清空,也就是棋盘的初始化工作。在这个函数中,主要发生了这么几件事情:l 将m_data中每一个落子位都置为无子状态(-1)。l 按照传入的参数设置棋盘等待标志m_bWait,以供先、后手的不同情况之用l 使用delete将m_pGame指针所指向的原有游戏模式对象从堆上删除。3.绘制棋子Draw这是非常重要的一个函数,它根据参数给定的坐标和颜色绘制棋子。绘制的详细过程如下:l 将给定的棋盘坐标换算为绘图的像素坐标。l 根据坐标绘制棋子位图。l 如果先前曾下过棋子,则利用R2_NOTXORPEN将上一个绘制棋子上的最后落子指示矩形擦除。l 在刚绘制完成的棋子四周绘制最后落子指示矩形。4.左键消息OnLButtonUp作为棋盘唯一响应的左键消息,它需要相应的工作如下:l 如果棋盘等待标志m_bWait为TRUE,则直接发出警告声音并返回,即禁止落子。l 如果点击时的鼠标坐标在合法坐标(0, 0)(14, 14)之外,亦禁止落子。l 如果走的步数大于1步,方才允许悔棋。l 进行胜利判断,如胜利则修改UI状态并增加胜利数的统计。l 如未胜利,则向对方发送已经落子的消息。l 落子完毕,将m_bWait标志置为TRUE,开始等待对方回应。5.绘制棋盘OnPaint每当WM_PAINT消息触发时,都需要对棋盘进行重绘。OnPaint作为响应绘制消息的消息处理函数使用了双缓冲技术,减少了多次绘图可能导致的图像闪烁问题。这个函数主要完成了以下工作:l 装载棋盘位图并进行绘制。l 根据棋盘数据绘制棋子。l 绘制最后落子指示矩形。6.对方落子完毕Over在对方落子之后,仍然需要做一些判断工作,这些工作与OnLButtonUp中的类似。 7.设置游戏模式SetGameMode这个函数通过传入的游戏模式参数对m_pGame指针进行了初始化,代码如下:void CTable:SetGameMode( int nGameMode ) if ( 1 = nGameMode ) m_pGame = new COneGame( this ); else m_pGame = new CTwoGame( this ); m_pGame-Init();这之后,就可以利用OO的继承和多态特点来使m_pGame指针使用相同的调用来完成不同的工作了,实际上,COneGame:Init和CTwoGame:Init都是不同的。8.胜负的判断WinWin是游戏中一个极其重要的算法,用来判断当前棋盘的形势是哪一方获胜。其详细内容请参见“主要算法”一节。四、游戏模式类CGame CGame类负责对游戏模式进行管理,以及在不同的游戏模式下对不同的用户行为进行不同的响应。由于并不需要CGame本身进行响应,所以将其设计为了一个纯虚类,它的定义如下:class CGameprotected: CTable *m_pTable;public: / 落子步骤 list 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;(一)主要成员变量说明1.棋盘指针m_pTable由于在游戏中需要对棋盘以及棋盘的父窗口主对话框进行操作及UI状态设置,故为CGame类设置了这个成员。当对主对话框进行操作时,可以使用m_pTable-GetParent()得到它的窗口指针。2.落子步骤m_StepList一个好的棋类程序必须要考虑到的功能就是它的悔棋功能,所以需要为游戏类设置一个落子步骤的列表。由于人机对弈和网络对弈中都需要这个功能,故将这个成员直接设置到基类CGame中。另外,考虑到使用的简便性,这个成员使用了C+标准模板库10(Standard Template Library,STL)中的std:list,而不是MFC的CList。(二)主要成员函数说明1.悔棋操作Back在不同的游戏模式下,悔棋的行为是不一样的。人机对弈模式下,计算机是完全允许玩家悔棋的,但是出于对程序负荷的考虑(此原因请参见“几点补充说明”一节),只允许玩家悔当前的两步棋(计算机一步,玩家一步)。双人网络对弈模式下,悔棋的过程为:首先由玩家向对方发送悔棋请求(悔棋消息),然后由对方决定是否允许玩家悔棋,在玩家得到对方的响应消息(允许或者拒绝)之后,才进行悔棋与否的操作。2.初始化操作Init对于不同的游戏模式而言,也就有不同的初始化方式。对于人机对弈模式而言,初始化操作包括以下几个步骤:l 设置网络连接状态m_bConnected为FALSE。l 设置主界面计算机玩家的姓名。l 初始化所有的获胜组合。l 如果是计算机先走,则占据天元(棋盘正中央)的位置。网络对弈的初始化工作暂为空,以供以后扩展之用。3.接收来自对方的消息ReceiveMsg这个成员函数由CTable棋盘类的Receive成员函数调用,用于接收来自对方的消息。对于人机对弈游戏模式来说,所能接收到的就仅仅是本地模拟的落子消息MSG_PUTSTEP;对于网络对弈游戏模式来说,这个成员函数则负责从套接字读取对方发过来的数据,然后将这些数据解释为自定义的消息结构,并回到CTable:Receive来进行处理。4.发送落子消息SendStep在玩家落子结束后,要向对方发送自己落子的消息。对于不同的游戏模式,发送的目标也不同:l 对于人机对弈游戏模式,将直接把落子的信息(坐标、颜色)发送给COneGame类相应的计算函数。l 对于网络对弈游戏模式,将把落子消息发送给套接字,并由套接字转发给对方。5.胜利后的处理Win这个成员函数主要针对CTwoGame网络对弈模式。在玩家赢得棋局后,这个函数仍然会调用SendStep将玩家所下的制胜落子步骤发送给对方玩家,然后对方的游戏端经由CTable:Win来判定自己失败。五、消息机制Windows系统拥有自己的消息机制,在不同事件发生的时候,系统也可以提供不同的响应方式。五子棋程序也模仿Windows系统实现了自己的消息机制,主要为网络对弈服务,以响应多种多样的网络消息。(一)消息机制的架构当继承自CAsyncSocket的套接字类CFiveSocket收到消息时,会触发CFiveSocket:OnReceive事件,在这个事件中调用CTable:Receive,CTable:Receive开始按照自定义的消息格式接收套接字发送的数据,并对不同的消息类型进行分发处理。如图3所示,当CTable获得了来自网络的消息之后,就可以使用一个switch结构来进行消息的分发了。图3 自定义的消息机制(二)各种消息说明网络间传递的消息,都遵循以下一个结构体的形式:/ 摘自Messages.htypedef struct _tagMsgStruct / 消息ID UINT uMsg; / 落子信息 int x; int y; int color; / 消息内容 TCHAR szMsg128; MSGSTRUCT;随着uMsg表示消息ID,x、y表示落子的坐标,color表示落子的颜色,szMsg随着uMsg的不同而有不同的含义。l 落子消息MSG_PUTSTEP表明对方落下了一个棋子,其中x、y和color成员有效,szMsg成员无效。在人机对弈游戏模式下,亦会模拟发送此消息以达到程序模块一般化的效果。l 悔棋消息MSG_BACK表明对方请求悔棋,除uMsg成员外其余成员皆无效。接到这个消息后,会弹出MessageBox询问是否接受对方的请求(如图4所示),并根据玩家的选择回返MSG_AGREEBACK或MSG_REFUSEBACK消息。另外,在发送这个消息之后,主界面上的某些元素将不再响应用户的操作。图4 请求悔棋l 同意悔棋消息MSG_AGREEBACK表明对方接受了玩家的悔棋请求,除uMsg成员外其余成员皆无效。接到这个消息后,将进行正常的悔棋操作。l 拒绝悔棋消息MSG_REFUSEBACK表明对方拒绝了玩家的悔棋请求(如图5所示),除uMsg成员外其余成员皆无效。接到这个消息后,整个界面将恢复发送悔棋请求前的状态。图5 拒绝悔棋l 和棋消息MSG_DRAW表明对方请求和棋,除uMsg成员外其余成员皆无效。接到这个消息后,会弹出MessageBox询问是否接受对方的请求(如图6所示),并根据玩家的选择回返MSG_AGREEDRAW或MSG_REFUSEDRAW消息。另外,在发送这个消息之后,主界面上的某些元素将不再响应用户的操作。图6 请求和棋l 同意和棋消息MSG_AGREEDRAW表明对方接受了玩家的和棋请求(如图7所示),除uMsg成员外其余成员皆无效。接到这个消息后,双方和棋。图7 同意和棋l 拒绝和棋消息MSG_REFUSEDRAW表明对方拒绝了玩家的和棋请求(如图8所示),除uMsg成员外其余成员皆无效。接到这个消息后,整个界面将恢复发送和棋请求前的状态。图8 拒绝和棋l 认输消息MSG_GIVEUP表明对方已经投子认输(如图9所示),除uMsg成员外其余成员皆无效。接到这个消息后,整个界面将转换为胜利后的状态。l 聊天消息MSG_CHAT表明对方发送了一条聊天信息,szMsg表示对方的信息,其余成员无效。接到这个信息后,会将对方聊天的内容显示在主对话框的聊天记录窗口内。图9 认输l 对方信息消息MSG_INFORMATION用来获取对方玩家的姓名,szMsg表示对方的姓名,其余成员无效。在开始游戏的时候,由客户端向服务端发送这条消息,服务端接到后设置对方的姓名,并将自己的姓名同样用这条消息回发给客户端。l 再次开局消息MSG_PLAYAGAIN表明对方希望开始一局新的棋局,除uMsg成员外其余成员皆无效。接到这个消息后,会弹出MessageBox询问是否接受对方的请求(如图10所示),并根据玩家的选择回返MSG_AGREEAGAIN消息或直接断开网络。图10 再次开局l 同意再次开局消息MSG_AGREEAGAIN表明对方同意了再次开局的请求,除uMsg成员外其余成员皆无效。接到这个消息后,将开启一局新游戏。六、主要算法 五子棋游戏中,有相当的篇幅是算法的部分。无论是人机对弈,还是网络对弈,都需要合理算法的支持,本节中将详细介绍五子棋中使用的算法。(一)判断胜负五子棋的胜负,在于判断棋盘上是否有一个点,从这个点开始的右、下、右下、左下四个方向是否有连续的五个同色棋子出现,如图11所示。图11 判断胜负方向这个算法也就是CTable的Win成员函数。从设计的思想上,需要它接受一个棋子颜色的参数,然后返回一个布尔值,这个值来指示是否胜利,代码如下:BOOL CTable:Win( int color ) const int x, y; / 判断横向 for ( y = 0; y 15; y+ ) for ( x = 0; x 11; x+ ) if ( color = m_dataxy &color = m_datax + 1y & color = m_datax + 2y &color = m_datax + 3y & color = m_datax + 4y ) return TRUE; / 判断纵向 for ( y = 0; y 11; y+ ) for ( x = 0; x 15; x+ ) if ( color = m_dataxy &color = m_dataxy + 1 & color = m_dataxy + 2 &color = m_dataxy + 3 & color = m_dataxy + 4 ) return TRUE; / 判断“”方向 for ( y = 0; y 11; y+ ) for ( x = 0; x 11; x+ ) if ( color = m_dataxy &color = m_datax + 1y + 1 & color = m_datax + 2y + 2 &color = m_datax + 3y + 3 & color = m_datax + 4y + 4 ) return TRUE; / 判断“/”方向 for ( y = 0; y 11; y+ ) for ( x = 4; x 15; x+ ) if ( color = m_dataxy &color = m_datax - 1y + 1 & color = m_datax - 2y + 2 &color = m_datax - 3y + 3 & color = m_datax - 4y + 4 ) return TRUE; / 不满足胜利条件 return FALSE;由于这个算法所遵循的搜索顺序是从左到右、自上而下,因此在每次循环的时候,都有一些坐标无需纳入考虑范围。例如对于横向判断而言,由于右边界所限,因而所有横坐标大于等于11的点,都构不成达到五子连的条件,所以横坐标的循环上界也就定为11,这样也就提高了搜索的速度。(二)人机对弈算法人机对弈算法完全按照CGame基类定义的接口标准,封装在了COneGame派生类之中。下面将对这个算法进行详细地介绍。1.获胜组合获胜组合是一个三维数组,它记录了所有取胜的情况。也就是说,参考于CTable:Win中的情况,对于每一个落子坐标,获胜的组合一共有15 * 11 * 2 + 11 * 11 * 2 = 572种。而对于每个坐标的获胜组合,应该设置一个1515572大小的三维数组。在拥有了这些获胜组合之后,就可以参照每个坐标的572种组合给自己的局面和玩家的局面进行打分,也就是根据当前盘面中某一方所拥有的获胜组合多少进行权值的估算,给出最有利于自己的一步落子坐标。由于是双方对弈,所以游戏的双方都需要一份获胜组合,也就是:bool m_Computer1515572; / 电脑获胜组合bool m_Player1515572; / 玩家获胜组合在每次游戏初始化(COneGame:Init)的时候,需要将每个坐标下可能的获胜组合都置为true。此外,还需要设置计算机和玩家在各个获胜组合中所填入的棋子数:int m_Win2572;在初始化的时候,将每个棋子数置为0。2.落子后处理每当一方落子后,都需要作如下处理:如果己方此坐标的获胜组合仍为true,且仍有可能在此获胜组合处添加棋子,则将此获胜组合添加棋子数加1;如果对方此坐标的获胜组合仍为true,则将对方此坐标的获胜组合置为false,并将对方此获胜组合添加棋子数置为-1(不可能靠此组合获胜)。以玩家落子为例,代码为:for ( i = 0; i 572; i+ ) / 修改状态变化 if ( m_PlayerstepPut.xstepPut.yi &m_Win0i != -1 ) m_Win0i+; if ( m_ComputerstepPut.xstepPut.yi ) m_ComputerstepPut.xstepPut.yi = false; m_Win1i = -1; 3.查找棋盘空位在计算机落子之前,需要查找棋盘的空位,所以需要一个SearchBlank成员函数完成此项工作,此函数需要进行不重复的查找,也就是说,对已查找过的空位进行标记,并返回找到空位的坐标,其代码如下:bool COneGame:SearchBlank( int &i, int &j,int nowTable15 ) int x, y; for ( x = 0; x 15; x+ ) for ( y = 0; y 15; y+ ) if ( nowTablexy = -1 & nowTablexy != 2 ) i = x; j = y; return true; return false;4.落子打分找到空位后,需要对这个点的落子进行打分,这个分数也就是这个坐标重要性的体现,代码如下:int COneGame:GiveScore( const STEP& stepPut ) int i, nScore = 0; for ( i = 0; i GetColor() = stepPut.color ) / 玩家下 if ( m_PlayerstepPut.xstepPut.yi ) switch ( m_Win0i ) case 1: nScore -= 5; break; case 2: nScore -= 50; break; case 3: nScore -= 500; break; case 4: nScore -= 5000; break; default: break; else / 计算机下 if ( m_ComputerstepPut.xstepPut.yi ) switch ( m_Win1i ) case 1: nScore += 5; break; case 2: nScore += 50; break; case 3: nScore += 100; break; case 4: nScore += 10000; break; default: break; return nScore;如代码所示,考虑到攻守两方面的需要,所以将玩家落子给的分数置为负值。5.防守策略落子的考虑不单单要从进攻考虑,还要从防守考虑。这一细节的实现其实就是让计算机从玩家棋盘布局分析战况,然后找出对玩家最有利的落子位置。整个过程如下:for ( m = 0; m GetColor(); step.x = i; step.y = j; ptemp = GiveScore( step );if ( pscore ptemp ) / 此时为玩家下子,运用极小极大法时应选取/最小值 pscore = ptemp;for ( m = 0; m cscore ) cscore = ctemp + pscore; bestx = pi; besty = pj;在这之后,重新改变一下棋盘的状态(2)即可。七、补充说明l 考虑到程序的响应速度,人机对弈算法只对玩家的棋子进行了一步的推测。l 由于计算机在落子时选取的是得分最高的一步落子,所以如果玩家在开局的时候不改变落子步骤,那么将会获得从头至尾相同的棋局。l 考虑到下棋同时还要聊天,所以并未对落子时间加入任何限制,同样如果玩家离开游戏也不会判负。l 对于人机对弈的悔棋处理,由于这个算法的开销相当大,每一步落子都会存在不同的棋盘布局,所以实现从头到尾的悔棋不是很现实(将会存在过多的空间保存棋盘布局),因而在人机对弈模式下,只允许玩家悔最近的两步落子。八、结束语通过编写这个程序,我体会最为深刻的一点是系统架构和设计模式的重要性。即使是对于一个并不大的程序,代码的组织都是非常重要的,因为这关系到日后的维护以及扩展。这个游戏之中,有关网络Socket编程或者博弈树算法的知识都可以直接从无所不包的Internet上获取,甚至可以直接获得一个完整的五子棋人机对弈算法的源代码级模块。但是对于系统的架构,却完全是自己的事情,几千上万行的代码需要通过合适的方法组织起来,使程序员编写代码更加有条理,更加符合软件工程的标准,这才是最重要的。在刚开始编写这个程序的时候,我幼稚地认为其中最重要的是博弈树算法。但是头一个月编写程序的时候却发现程序越写越不容易维护,可见是我走错了方向。后来我向公司真正的软件设计人员及系统架构师讨教,他们告诉我:我们的先人早已为我们准备好了各种精良可用的现成算法,我们所要做的就是直接“拿来主义”罢了;但是对于代码的组织(也就是软件的架构)才是真正软件工业的核心部分,因为软件事实上是直接和经济挂钩的,因此我们必须在编写代码之前选择一种最为合适的方法来组织这些代码,否则我们将会失去更多的时间和金钱。于是,我将以前写的代码全部删除,认真地思考了几天。我也在这几天内真正从一个学生程序员走入了软件开发的大门,我开始发现其实软件开发并不是纯数学正相反,数学只占了很小的一部分。它其实是一种哲学,一种有着数学美感的哲学。九、致谢在本次毕业设计中,曾遇到过不少问题,如果只靠我个人的努力,很难按时完成毕业设计(虽然只是写一篇论文和和简单的程序设计),在此,我衷心感谢我的指导老师潘浪老师,从他身上学到了很多东西。认真负责的工作态度,严谨的治学精神和深厚的理论水平都使我获益匪浅,他严格的要求更是使我在过程中明白要扎实的学习,无论在理论上还是在程序设计方面遇到的问题都是找指导老师帮助的,给予我无私帮助和悉心的教导,使我的毕业设计得以顺利的按时完成。另外,我还要感谢在大学四年来对我有所教导的老师,他们孜孜不倦的教诲不但让我学到了很多知识,而且使我掌握了学习的方法,更教会了我为人处世的道理,在此表示感谢。由于毕业设计时间较短,同时还要兼顾日常工作和其他方面的学习,所以该毕业设计还有许多不尽如人意的地方,这些都有待今后进一步加强、改进、完善,不过我想我一定会在今后的过程中不断地学习,自我加强,使自己取得更大的进步,并在各方面去全面的学习和发展。对于在大学里面所有老师们的悉心教导以及同学们对我的帮助,我衷心的表示感谢。参考文献1 潘爱民:Microsoft Visual C+.NET 技术内幕(第6版),清华大学出版社,1999年10月。2 汪晓平、钟军:Visual C+网络通信协议分析与应用实现,人民邮电出版社,2001年1月。3 刘宗田、邢大红、孙慧杰:C+编程思想,机械工业出版社,2002年10月。4 Jesse Liberty著:21天学通C+,人民邮电出版社,2003年5月。5 侯捷、孟岩:C+标准程序库,华中科技大学出版社,2006年11月。6 Charles Petzold:Windows程序设计,北京大学出版社,2002年1月。7 易君:Visual C+.NET网络编程,中国铁道出版社,2003年5月。8 李英军:深入浅出MFC(第2版),机械工程出版社,2001年2月。9 王咏刚:MSDN for Visual Studio 6.0,电子工业出版社,2003年6月10 侯俊杰:Microsoft Visual C+编程,人民邮电出版社,2004年9月。姓 名学 号专 业设计题目评价项目具 体 要 求分 值评 分资料收集方案论证能独立查阅文献资料;具有收集、整理相关信息及获取新知识的能力;实施方案的分析、论证正确可行。10研究与设计能力能综合运用基础知识和专业知识,独立地完成主要模块设计和系统设计。20设计质量设计方法正确、合理;设计内容系统、完整;说明书编写层次分明、条理清晰、符合规范要求。20实际动手能力完成电路图设计、PCB板设计或编程设计;完成硬件、软件的安装调试和测试结果的整理与分析。20工作量与工作态度按期圆满完成规定的任务,工作量饱满,难度较大;工作努力,遵守纪律;工作作风严谨务实。20学术水平与创新有一定学术水平或应用价值;研究方法和设计手段有所创新,或在前人工作的基础上有改进、突破。10是否同意参加答辩:同意( ) 不同意( )总分综合评语:指导教师(签名): 年 月 日
展开阅读全文