辅助文档_空棋位算法.doc_第1页
辅助文档_空棋位算法.doc_第2页
辅助文档_空棋位算法.doc_第3页
辅助文档_空棋位算法.doc_第4页
辅助文档_空棋位算法.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录1引言11.1五子棋介绍11.2开发背景11.3开发环境及运行环境11.3.1开发环境11.3.2运行环境12软件架构22.1棋盘类22.2游戏模式类23棋盘类CTable43.1主要成员变量说明43.1.1棋盘等待标志m_bWait43.1.2棋盘数据m_data43.2主要成员函数说明43.2.1清空棋盘Clear43.2.2绘制棋子Draw43.2.3左键消息OnLButtonUp53.2.4绘制棋盘OnPaint53.2.5对方落子完毕Over53.2.6设置游戏模式SetGameMode53.2.7胜负的判断Win64游戏模式类CGame74.1主要成员变量说明74.1.1棋盘指针m_pTable74.1.2落子步骤m_StepList84.2主要成员函数说明84.2.1初始化操作Init84.2.2发送自己落子消息 SentStep84.2.3胜利后的处理Win85主要算法95.1判断胜负95.2人机对弈算法115.2.1获胜组合115.2.2落子后处理125.2.3查找棋盘空位135.2.4落子打分135.2.5防守策略155.2.6选取最佳落子176几点补充说明18五子棋空棋位打分算法1引言1.1五子棋介绍五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。1.2开发背景当前网络上流传的五子棋游戏功能并不尽善尽美,其中最主要的问题就是人机对战和网络对战不能够一起实现,所以决定开发1一个既能够人机对战,又能够进行网络对战的五子棋系统。1.3开发环境及运行环境1.3.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.01.3.2运行环境l Intel Pentium 2及以上处理器,32M以上内存,4G以上硬盘l Microsoft Windows 9X/NT操作系统l 800*600或以上的屏幕分辨率第 18 页 共 18 页2软件架构软件的总体架构如图2.1:二人游戏类一人游戏类游戏类指针棋盘类主界面用户图2.1 软件架构考虑到整个的下棋过程(无论对方是电脑抑或其他网络玩家)可以分为:己方落子、等待对方落子、对方落子、设置己方棋盘数据这一系列过程,因此一人游戏类、二人游戏类和棋盘类之间的关系参考了AbstractFactory(抽象工厂)模式,以实现对两个不同模块进行一般化的控制。22.1棋盘类整个架构的核心部分,类名为CTable。封装了棋盘的各种可能用到的功能3,如保存棋盘数据、初始化、判断胜负等。用户操作主界面,主界面与CTable进行交互来完成对游戏的操作。2.2游戏模式类用来管理人机对弈/网络对弈两种游戏模式,类名为CGame。CGame是一个抽象类,经由它派生出一人游戏类COneGame和网络游戏类CTwoGame,如图2.2:抽象类CGameCOneGameCTwoGame 图2.2 CGame类派生关系这样,CTable类就可以通过一个CGame类的指针4,在游戏初始化的时候根据具体游戏模式的要求实例化COneGame或CTwoGame类的对象;然后利用多态性5,使用CGame类提供的公有接口就可以完成不同游戏模式下的不同功能了。3棋盘类CTable3.1主要成员变量说明3.1.1棋盘等待标志m_bWait由于在玩家落子后需要等待对方落子,m_bWait标志就用来标识棋盘的等待状态。当m_bWait为TRUE时,是不允许玩家落子的。3.1.2棋盘数据m_data这是一个15*15的二位数组,用来保存当前棋盘的落子数据。其中对于每个成员来说,0表示落黑子,1表示落白子,-1表示无子。3.1.3游戏模式指针m_pGame这个CGame类的对象指针是CTable类的核心内容。它所指向的对象实体决定了CTable在执行一件事情时候的不同行为,具体的内容请参见“游戏模式”一节。3.2主要成员函数说明3.2.1清空棋盘Clear在每一局游戏开始的时候都需要调用这个函数将棋盘清空,也就是棋盘的初始化工作。在这个函数中,主要发生了这么几件事情:l 将m_data中每一个落子位都置为无子状态(-1)。l 按照传入的参数设置棋盘等待标志m_bWait,以供先、后手的不同情况之用。l 使用delete将m_pGame指针所指向的原有游戏模式对象从堆上删除。3.2.2绘制棋子Draw这无疑是很重要的一个函数,它根据参数给定的坐标和颜色绘制棋子。绘制的详细过程如下:l 将给定的棋盘坐标换算为绘图的像素坐标。l 根据坐标绘制棋子位图。l 如果先前曾下过棋子,则利用R2_NOTXORPEN将上一个绘制棋子上的最后落子指示矩形擦除。l 在刚绘制完成的棋子四周绘制最后落子指示矩形。3.2.3左键消息OnLButtonUp作为棋盘唯一响应的左键消息,也需要做不少的工作:l 如果棋盘等待标志m_bWait为TRUE,则直接发出警告声音并返回,即禁止落子。l 如果点击时的鼠标坐标在合法坐标(0, 0)(14, 14)之外,亦禁止落子。l 进行胜利判断,如胜利则修改UI状态并增加胜利数的统计。l 如未胜利,则调用落子的函数。l 落子完毕,将m_bWait标志置为TRUE,开始等待对方回应。3.2.4绘制棋盘OnPaint每当WM_PAINT消息触发时,都需要对棋盘进行重绘。OnPaint作为响应绘制消息的消息处理函数使用了双缓冲技术,减少了多次绘图可能导致的图像闪烁问题。这个函数主要完成了以下工作:l 装载棋盘位图并进行绘制。l 根据棋盘数据绘制棋子。l 绘制最后落子指示矩形。3.2.5对方落子完毕Over在对方落子之后,仍然需要做一些判断工作,这些工作与OnLButtonUp中的类似,在此不再赘述。3.2.6设置游戏模式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的继承和多态特点8来使m_pGame指针使用相同的调用来完成不同的工作了,事实上,COneGame:Init和CTwoGame:Init都是不同的。3.2.7胜负的判断Win这是游戏中一个极其重要的算法,用来判断当前棋盘的形势是哪一方获胜。其详细内容请参见“主要算法”一节。4游戏模式类CGame这个类负责对游戏模式进行管理,以及在不同的游戏模式下对不同的用户行为进行不同的响应。由于并不需要CGame本身进行响应,所以将其设计为了一个纯虚类9,它的定义如下: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 SentStep( const STEP& stepSend ) = 0; ;4.1主要成员变量说明4.1.1棋盘指针m_pTable由于在游戏中需要对棋盘以及棋盘的父窗口主对话框进行操作及UI状态设置,故为CGame类设置了这个成员。当对主对话框进行操作时,可以使用m_pTable-GetParent()得到它的窗口指针。4.1.2落子步骤m_StepList一个好的棋类程序必须要考虑到的功能就是它的悔棋功能,所以需要为游戏类设置一个落子步骤的列表。由于人机对弈和网络对弈中都需要这个功能,故将这个成员直接设置到基类CGame中。另外,考虑到使用的简便性,这个成员使用了C+标准模板库10(Standard Template Library,STL)中的std:list,而不是MFC的CList。4.2主要成员函数说明4.2.1初始化操作Init对于不同的游戏模式而言,也就有不同的初始化方式。对于人机对弈模式而言,初始化操作包括以下几个步骤:l 初始化所有的获胜组合。l 如果是计算机先走,则占据天元(棋盘正中央)的位置。网络对弈的初始化工作暂为空,以供以后扩展之用。4.2.2发送自己落子消息 SentStep在玩家落子结束后,要向对方发送自己落子的消息。对于不同的游戏模式,发送的目标也不同:对于人机对弈游戏模式,将直接把落子的信息(坐标、颜色)发送给COneGame类相应的计算函数。4.2.3胜利后的处理Win这个成员函数主要针对CTwoGame网络对弈模式。在玩家赢得棋局后,这个函数仍然会调用SendStep将玩家所下的制胜落子步骤发送给对方玩家,然后对方的游戏端经由CTable:Win来判定自己失败。5主要算法五子棋游戏中,有相当的篇幅是算法的部分。无论是人机对弈,还是网络对弈,都需要合理算法的支持,本节中将详细介绍五子棋中使用的算法。135.1判断胜负五子棋的胜负,在于判断棋盘上是否有一个点,从这个点开始的右、下、右下、左下四个方向是否有连续的五个同色棋子出现,如图6.1:图6.1 判断胜负方向这个算法也就是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,这样也就提高了搜索的速度。5.2人机对弈算法人机对弈算法完全按照CGame基类定义的接口标准,封装在了COneGame派生类之中。下面将对这个算法进行详细地介绍。145.2.1获胜组合获胜组合是一个三维数组,它记录了所有取胜的情况。也就是说,参考于CTable:Win中的情况,对于每一个落子坐标,获胜的组合一共有15 * 11 * 2 + 11 * 11 * 2 = 572种。而对于每个坐标的获胜组合,应该设置一个1515572大小的三维数组。在拥有了这些获胜组合之后,就可以参照每个坐标的572种组合给自己的局面和玩家的局面进行打分,也就是根据当前盘面中某一方所拥有的获胜组合多少进行权值的估算,给出最有利于自己的一步落子坐标。由于是双方对弈,所以游戏的双方都需要一份获胜组合,也就是:bool m_Computer1515572; / 电脑获胜组合bool m_Player1515572; / 玩家获胜组合在每次游戏初始化(COneGame:Init)的时候,需要将每个坐标下可能的获胜组合都置为true。例如,下图是其中一种获胜组合(其中0表示无子,1表示有子):此外,还需要设置计算机和玩家在各个获胜组合中所填入的棋子数:int m_Win2572;在初始化的时候,将每个棋子数置为0。5.2.2落子后处理每当一方落子后,都需要作如下处理:l 如果己方此坐标的获胜组合仍为true,且仍有可能在此获胜组合处添加棋子,则将此获胜组合添加棋子数加1;l 如果对方此坐标的获胜组合仍为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; 5.2.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;5.2.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.xstepPu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论