人机对战五子棋经典算法

合集下载

五子棋人工智能权重估值算法

五子棋人工智能权重估值算法

五子棋人工智能权重估值算法五子棋人工智能权重估值算法一、五子棋介绍五子棋是中国古代的传统黑白棋种之一。

现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。

五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。

五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。

它是中西文化的交流点,是古今哲理的结晶。

黑白双方依次落子,任一方先在棋盘上形成横向、竖向、斜向的连续的相同颜色的五个(含五个以上)棋子的一方为胜。

这种规则适合初学的五子棋爱好者。

因为这种规则下黑棋胜算较大。

甚至已经有人证明在黑白双方都不出现错误的情况下,黑棋可以必胜。

所以一般要求连续玩两盘,即任一方执黑,执白各一次。

二、逻辑变量与常量逻辑变量与常量的分析如下:Public Const Five As Integer = 3000 '五子连线得分Public Const FFDL As Integer = 2900 '双活四得分Public Const FFSL As Integer = 2800 '活四成四得分Public Const FTDL As Integer = 2700 '活四活三得分Public Const FL As Integer = 2600 '单活四得分Public Const FFNL As Integer = 2500 '双成四得分Public Const FTSL As Integer = 2400 '成四活三得分Public Const TTDL As Integer = 2300 '双活三得分Public X%, Y% '水平与垂直坐标Public Xt%, Yt% '临时横纵坐标Public CountNum% '棋步总数记录变量Public Piece() As Integer ' 0表示空闲,1为玩家1,2为玩家2Public Piecet() As Integer '用于估值函数使用的临时数组Public GameOrNot As Boolean '是否游戏中Public Flag As Byte '行棋变量,表示该谁下棋,数值与棋子变量相同Public PieceRec() As Integer '定义棋步记录变量以记录所走棋步Public AIOrNot As Boolean '是否人机对战模式,人机对战则为TruePublic LBlock(4) As Boolean, RBlock(4) As Boolean '左堵右堵记录变量数组Public EmptyNumE(4) As Byte '定义空个数记录变量数组Public PieceNum(4) As Byte '定义棋子个数记录数组Public ScoreE(4) As Integer '定义得分数组Public ScoreS As Integer '定义得分记录空间变量Public FirstMove As Boolean '是否玩家先行注:以上声明均在模块中进行。

人机对战五子棋游戏算法

人机对战五子棋游戏算法

人机对战五子棋游戏算法2007年08月29日星期三 20:07此算法计算机会辨别在同一条直线或者对角线上的棋子个数是玩家的多还是计算机的多.若玩家的多,计算机就会把棋子下到玩家最有可能获胜的位置上,相反如果计算机的多,计算机就会把棋子下到自己最有可能获胜的位置上.效果图如下:此函数为自定义函数,表示轮到玩家下棋void CFiveChessDlg::computerTurn(){//计算玩家在空格子中的获胜分数for(i=0;i<10;i++){for(j=0;j<10;j++){playerGrades[i][j]=0;if(2==board[i][j]){for(k=0;k<192;k++){if(playerTable[i][j][k]){switch(chessCount[0][k]){case 1:playerGrades[i][j]+=5;break;case 2:playerGrades[i][j]+=50;break;case 3:playerGrades[i][j]+=100; break;case 4:playerGrades[i][j]+=400; break;}}}}}}//计算计算机在空格子中的获胜分数for(i=0;i<10;i++){for(j=0;j<10;j++){computerGrades[i][j]=0;if(2==board[i][j]){for(k=0;k<192;k++){if(computerTable[i][j][k]){switch(chessCount[1][k]){case 1:computerGrades[i][j]+=5; break;case 2:computerGrades[i][j]+=50; break;case 3:computerGrades[i][j]+=100; break;case 4:computerGrades[i][j]+=400; break;}}}}}}if(start==true)//游戏开始,计算机第一次下棋时执行{if(2==board[4][4]){m=4;n=4;}else{m=5;n=5;}start=false;}else{for(i=0;i<10;i++){for(j=0;j<10;j++){if(2==board[i][j]){if(computerGrades[i][j]>=computerTopGrade){computerTopGrade=computerGrades[i][j];computerTopGradeX=i;computerTopGradeY=j;}if(playerGrades[i][j]>=playerTopGrade){playerTopGrade=playerGrades[i][j];playerTopGradeX=i;playerTopGradeY=j;}}}}if(computerTopGrade>=playerTopGrade)//攻击,计算机较具优势 {m=computerTopGradeX; //将棋子摆在自己最有可能获胜的位置上进行攻击n=computerTopGradeY;}{m=playerTopGradeX; ////将棋子摆在玩家最有可能获胜的位置上进行防守n=playerTopGradeY;}}computerTopGrade=0;playerTopGrade=0;board[m][n]=1; //设定为计算机的棋子computerCount++;if((50==playerCount)&&(50==computerCount)){tie=true;over=true;}for(i=0;i<192;i++){if(computerTable[m][n][i]&&chessCount[1][i]!=6){chessCount[1][i]++;}if(playerTable[m][n][i]){playerTable[m][n][i]=false;chessCount[0][i]=6;}}player=true;computer=false;}OnTimer函数用来没间隔一段时间执行的函数,程序每间隔一段时间来判断是轮到计算机下棋还是玩家下棋,然后贴上相应的棋子void CFiveChessDlg::OnTimer(UINT nIDEvent){// TODO: Add your message handler code here and/or call default if(!over){if(computer)computerTurn();for(i=0;i<=1;i++){for(j=0;j<192;j++)if(5==chessCount[i][j]) //判断任一方在任意一个获胜组合中是否有5个棋子{if(0==i){playerWin=true;over=true;break;}else{computerWin=true;over=true;break;}}if(over)break;}}}GetDlgItem(IDC_TIPSTATIC)->SetWindowText("小样,该你下了......");//没有任一方获胜for(i=0;i<10;i++){for(j=0;j<10;j++){if(0==board[i][j]) //贴上玩家棋子{BITMAP bm;CDC dcMem;CDC* pDC;CBitmap *pGreenBmp;CBitmap *pOldBitmap;pDC=GetDC();pGreenBmp=new CBitmap;pGreenBmp->LoadBitmap(IDB_GREENBMP);pGreenBmp->GetObject(sizeof(BITMAP),(LPVOID)&bm); dcMem.CreateCompatibleDC(pDC);pOldBitmap=dcMem.SelectObject(pGreenBmp);pDC->BitBlt(i*50+13,j*50+13,46,46,&dcMem,0,0,SRCCOP Y);delete pDC->SelectObject(pOldBitmap);}if(1==board[i][j]) //贴上计算机棋子{BITMAP bm1;CDC dcMem1;CDC* pDC1;CBitmap *pPurpleBmp;CBitmap *pOldBitmap1;pDC1=GetDC();pPurpleBmp=new CBitmap;pPurpleBmp->LoadBitmap(IDB_PURPLEBMP);pPurpleBmp->GetObject(sizeof(BITMAP),(LPVOID)&bm1); dcMem1.CreateCompatibleDC(pDC1);pOldBitmap1=dcMem1.SelectObject(pPurpleBmp);pDC1->BitBlt(i*50+13,j*50+13,46,46,&dcMem1,0,0,SRCC OPY);delete pDC1->SelectObject(pOldBitmap1);}}}if(playerWin)GetDlgItem(IDC_TIPSTATIC)->SetWindowText("不错啊,你居然赢了,恭喜恭喜!");if(computerWin)GetDlgItem(IDC_TIPSTATIC)->SetWindowText("哎!你这倒霉孩子,可怜哦,输了!");if(tie)GetDlgItem(IDC_TIPSTATIC)->SetWindowText("功夫相当,平分秋色!");CDialog::OnTimer(nIDEvent);}。

五子棋AI算法的改进方法讲解

五子棋AI算法的改进方法讲解

又是本人一份人工智能作业……首先道歉,从Word贴到Livewrter,好多格式没了,也没做代码高亮……大家凑活着看……想做个好的人机对弈的五子棋,可以说需要考虑的问题还是很多的,我们将制作拥有强大AI五子棋的过程分为十四步,让我来步步介绍。

第一步,了解禁手规则做一个五子棋的程序,自然对五子棋需要有足够的了解,现在默认大家现在和我研究五子棋之前了解是一样多的。

以这个为基础,介绍多数人不大熟悉的方面。

五子棋的规则实际上有两种:有禁手和无禁手。

由于无禁手的规则比较简单,因此被更多人所接受。

其实,对于专业下五子棋的人来说,有禁手才是规则。

所以,这里先对“有禁手”进行一下简单介绍:五子棋中“先手必胜”已经得到了论证,类似“花月定式”和“浦月定式”,很多先手必胜下法虽然需要大量的记忆,但高手确能做到必胜。

所以五子棋的规则进行了优化,得到了“有禁手”五子棋。

五子棋中,黑棋必然先行。

因此“有禁手”五子棋竞技中对黑棋有以下“禁手”限制:“三三禁”:黑棋下子位置同时形成两个以上的三;“四四禁”:黑棋下子位置同时形成两个以上的四;“长连禁”:六子以上的黑棋连成一线。

黑棋如下出“禁手“则马上输掉棋局。

不过如果“连五”与“禁手”同时出现这时“禁手”是无效的。

所以对于黑棋只有冲四活三(后面会有解释)是无解局面。

反观白棋则多了一种获胜方式,那就是逼迫黑棋必定要下在禁点。

为了迎合所有玩家,五子棋自然需要做出两个版本,或者是可以进行禁手上的控制。

第二步,实现游戏界面这里,我制作了一个简单的界面,但是,对于人机对弈来说,绝对够用。

和很多网上的精美界面相比,我的界面也许略显粗糙,但,开发速度较高,仅用了不到半天时间。

下面我们简单看下界面的做法。

界面我采用了WPF,表现层和逻辑层完全分开,前台基本可以通过拖拽完成布局,这里就不做过多介绍。

根据界面截图简单介绍1处实际上市两个渐变Label的拼接,2、3是两个label,4、5实际上是两个Button,但是没有做事件响应。

五子棋核心算法

五子棋核心算法

五子棋的核心算法时间:2010-03-26 20:50来源:网络作者:佚名点击:3115次介绍了五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。

五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。

这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。

介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。

一、相关的数据结构关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等操作。

1CList StepList;2//其中Step结构的表示为:34struct Step5{6int m;//m,n表示两个坐标值7int n;8char side;//side表示下子方9};10//以数组形式保存当前盘面的情况,11//目的是为了在显示当前盘面情况时使用:12char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];1314//其中FIVE_MAX_LINE表示盘面最大的行数。

1516//同时由于需要在递归搜索的过程中考虑时间和空间有效性,//只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,//这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合:1718CList CountList;19//其中类CBoardSituiton为:20class CBoardSituation21{22CList StepList; //每一步的列表23char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];24struct Step machineStep;//机器所下的那一步25double value;//该种盘面状态所得到的分数26}二、评分规则对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,|,/,\,//,\\实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一个简单的规则来表示当前棋面对机器方的分数。

五子棋几种算法详解

五子棋几种算法详解

五子棋几种算法详解算法一:这里讲述棋盘大小为10×10的人机对战五子棋实现方法,要看完整代码请看Java做的五子棋1.概述玩家每走一步,对于玩家和计算机,都根据获胜表对棋盘各个空棋位进行评分,每个位置的分数与下面这句话有关:该位置所在的每一种获胜组合中已经拥有的棋子数,然后对玩家和计算机产生的分数均衡,以判断计算机是进攻还是防守。

2.数据结构10×10的数据,用来记录棋盘状态;两个获胜表([10][10][192]),也就是获胜组合,因为五个子一线则胜,不在一线上的五个子就不在一个组合中,对于10×10的棋盘获胜的组合有192种,下面将会详细说明,获胜表用来表示棋盘上的每个位置是否在玩家或计算机的获胜组合中;一个二维数组([2][192]),记录玩家与计算机在各种获胜组合中填入了多少棋子;两个10×10的数组,用来记录玩家与计算机在各个棋盘位置上的分数,分数高的将是计算机下一步的着法。

3.计算获胜组合上图是一个10×10的五子棋棋盘,我们可以得出垂直方向上的获胜组合是10×6=60,同理,水平方向的获胜组合也是60,而两个倾斜方向上的获胜组合是(1+2+3+4+5)×2+6=36,即:60*2+36*2=192。

4.评分用两个数组存储每个棋位的分数,一个是计算机的,另一个是玩家的,表示该位置对于各方是最佳着法的肯定程度,对一个位置的评分就是:遍历该位置所在的每一种获胜组合,根据这个组合中已经拥有的己方棋子数1到4分别加不同分数,最后将这些所有的获胜组合所得出的分数相加就是该位置的分数,下图是对于黑方各棋位的评分(其中的1,2,3,4这几个值要根据实际需要来确定)。

5.思路算法二:1.关键词棋位:棋盘的任意一个能放置棋子的位置。

空棋位:没有放置棋子的棋位。

成五:同一色的五子连成一线,胜利。

活四:同一色的四子连成一线,且四子的两端是空棋位。

人工智能控制技术课件:五子棋对弈案例

人工智能控制技术课件:五子棋对弈案例

训练4400次的棋谱
课后习题
1.自己与五子棋自对弈软件对弈,实验验证五子棋自对弈
水平。
的当前玩家的奖赏值,及这一局中的每个棋盘状态 ;
2.将当前的棋盘状态 添加到 feature_planes_list 中,并根据 执行500
次蒙பைடு நூலகம்卡洛树搜索,得到∗ 和π ,注意这里的π是一个向量,维数
9×9=81,代表所有动作的移动概率。将π添加到 pi_list 中;
3.使用∗ 更新棋盘并判断游戏是否结束,如果还未结束回到步骤2,
示,在白方4、6、8已经连成3颗
时,黑方还不会去堵。而且在已
经连成4颗棋子的情况下,白方
居然没有绝杀黑方,而是下了12
这手棋。因此此时的五子棋自动
对弈还只会下前几手。
训练800次的棋谱
五子棋自对弈训练过程
右图是训练4400次的结果,可以看到训练到
4400局之后,五子棋已经掌握了开局和攻守
的诀窍。一开始双方就挨得很近,试图阻止
误差的方便,全连接层后会
有一个log_softmax,得到对
数概率log(p) ,如图所示。
Policy head
五子棋自动对弈实现原理
最后一个残差块的输出还会
输入Value head中,与Policy
head不同的是,Value head 里
面有两个全连接层:第一个
全连接层将输入映射为256维
为了提升网络的特征提取能力并
防止出现梯度消失问题,在卷积
层下面堆叠着19个或 39个
Residual block,如图所示,每个
Residual block由2个组成类似于
Convolutional block的子模块构成,

毕业设计(论文)-五子棋人机对弈程序设计[管理资料]

毕业设计(论文)-五子棋人机对弈程序设计[管理资料]

五子棋人机对弈程序摘要:五子棋程序由两个主要部分组成:一个估值函数和一个树状搜索算法。

而程序依靠估值函数来判断对于一方来说什么局面是好而什么局面是坏,后者是用来搜索几乎全部可能的棋步次序,目的是为了找出对于程序来说是最佳的一条路线。

人工智能电脑下棋模拟的是人类的智能,它的启发式搜索是边走边试探,即极大极小法。

关键词:五子棋人工智能估值函数树状搜索算法极大极小法The program for Renju in man vs computerAbstract:The program for Renju is composed of two parts: a evaluation function and a hashtable tree-searching algorithm. The evaluation function is used to judge the advantage or disadvantage situation for each part, the hashtabletree-searching algorithm is used to search almost all the possible steps and find out the best pathway for the program. The computer of Artificial Intelligence (AI) imitate the intelligence of human, its inspiring search way is Go and Explore, namely, Minimax.Key words:Renju Artificial Intelligence (AI)evaluation function hashtable tree-searching algorithmMinimax五子棋人机对弈程序目录中文摘要英文摘要第一章引言 (5) (5)、内容及作者的任务 (5)第二章研究现状及设计目标 (7) (7) (7) (8)第三章要解决的几个关键问题 (9) (9) (9) (9) (13) (13) (13) (14)第四章系统结构与模型 (16) (16) (16) (16)(Minimax Algorithm) (18)Alpha-Beta剪枝(Alpha-Beta Purning) (19) (21) (21) (22)第五章系统实现技术 (25) (25) (25) (28) (29) (31) (31) (33) (37)第六章性能测试与分析 (41)、硬件环境 (41) (41) (41) (42) (42)第七章结束语 (47)参考文献 (48)附录:程序清单(附光盘)第一章引言五子棋是起源于中国古代的传统黑白棋种之一。

五子棋人机对战系统设计

五子棋人机对战系统设计

摘要摘要计算机博弈是人工智能领域中主要研究的一个部分,为人工智能研究提供了多种重要的理论和方法,它涉及人工智能算法中的搜索方法、决策规划等。

通过对相关文献分析研究,按照人工智能和计算机博弈的一般原理做出优化改进,设计了一个智能五子棋游戏。

本文主要在以下三个方面进行研究:第一,研究了国内外手机游戏的发展状况,调查了五子棋游戏发展现状。

并且对手机开发游戏的平台做出选择。

第二,研究了博弈树的搜索技术以及α-β剪枝技术的基本原理及其改进方法,并对算法的效率作了分析。

第三,基于Visual C++6.0平台,根据五子棋系统自身的特点开发出了五子棋人机对战游戏,并对程序进行了功能测试和分析。

经过测试,本文开发五子棋游戏能够良好运行,能够满足人机对抗游戏需要。

关键词:五子棋,博弈树,极大极小搜索,α-β剪枝,估值函数IABSTRACTABSTRACTCompute game-playing is one of important portion to the artificial intelligence and general theory, which includes search method , decision programming and so on. According to study some relative works, a basic models of the Gobang game-playing systems is designed.Three aspects were done in the work:Firstly,the developing status of mobile phone game and Gobang game have ben studied. And Gobang game development platform is selected for this paper.Secondly,the earching technology of Game Tree is investigated.Further- more. Furthermore, the research of α-βprocedure and optimization problem of which based on it are imporved. At same time,we analyse the effect for α-βarithmetic .Thirdly, using Visual C++6.0 development platform and character of Gobang, A system is developed. Moreover, this game is tested and analysed. Result show that Gobang game can run well and satisfy the need of people playing.Key Words: Gobang, Game trees, Minimax Search, α-β pruning, Valuation functionII目录第一章绪论 (1)1.1选题意义和目的 (1)1.2国内外相关课题的研究现状 (2)1.3课题设计要求及目标 (3)1.4论文的主要研究思路 (3)第二章五子棋游戏的基础理论与技术 (4)2.1五子棋游戏的基础知识 (4)2.1.1 公平性问题 (4)2.2.3 脱离战场 (5)2.2.4 五子棋的诘棋 (5)2.2手机游戏开发平台技术 (6)2.2.1 各开发平台的介绍与分析 (6)2.2.2 确定开发平台 (15)2.3本章小结 (15)第三章五子棋系统的分析 (17)3.1五子棋游戏的规则分析 (17)3.2评分系统分析 (18)3.2.1 棋形分值表 (18)3.2.2 估值函数 (19)3.3五子棋人机对战核心算法分析——博弈树算法 (20)3.3.1 博弈树的定义 (20)3.3.2 局面的估值 (20)3.3.3 博弈树对极大极小值搜索 (21)3.3.4 α-β剪枝 (22)3.4本章小结 (26)第四章系统设计 (27)4.1程序流程图设计 (27)4.1.1 总体流程图 (27)III4.1.2 手机下棋流程图 (28)4.1.3 极大极小搜索流程图 (29)4.2开发环境简介 (30)4.2.1 Visual C++ 6.0简介 (30)4.2.2 MFC简介 (30)4.2.3 对话框类 (31)4.3五子棋游戏程序设计 (32)4.4本章小结 (34)第五章实现及应用测试 (35)5.1主要功能的实现 (35)5.1.1 手机下棋 (35)5.1.2 先走方设置 (36)5.1.3 难度级别设置 (36)5.1.4 悔棋功能 (37)5.1.5 判断输赢 (37)5.1.6 棋子的映射 (38)5.1.7 部分键盘消息的屏蔽 (38)5.1.8 线程同步与互斥 (38)5.1.9 计时功能 (39)5.2程序运行情况 (40)5.3程序棋力测试 (41)5.3.1 人和手机对弈 (41)5.3.2 手机不同级别之间的对弈 (42)5.4本章小结 (42)总结 (43)致谢 (44)参考文献 (45)IV第一章绪论第一章绪论1.1 选题意义和目的计算机的发展催生了一门新兴的学科—人工智能。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。

这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。

介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。

一、相关的数据结构
关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等操作。

CList StepList;
其中Step结构的表示为:
struct Step
{
int m; //m,n表示两个坐标值
int n;
char side; //side表示下子方
};
以数组形式保存当前盘面的情况,
目的是为了在显示当前盘面情况时使用:
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
其中FIVE_MAX_LINE表示盘面最大的行数。

同时由于需要在递归搜索的过程中考虑时间和空间有效性,只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合:
CList CountList;
其中类CBoardSituiton为:
class CBoardSituation
{
CList StepList; //每一步的列表
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
struct Step machineStep; //机器所下的那一步
double value; //该种盘面状态所得到的分数
}
二、评分规则
对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,&brvbar;,/,\,//,\\
实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一
个简单的规则来表示当前棋面对机器方的分数。

基本的规则如下:
判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予-100000 分;判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予-10000分;
判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予-5000 分;判断是否成死3活3,如果是机器方的话给予1000分,如果是人方的话给予-1000 分;判断是否能成死4,如果是机器方的话给予500分,如果是人方的话给予-500分;
判断是否能成单活3,如果是机器方的话给予200分,如果是人方的话给予-200分;
判断是否已成双活2,如果是机器方的话给予100分,如果是人方的话给予-100分;
判断是否能成死3,如果是机器方的话给予50分,如果是人方的话给予-50分;
判断是否能成双活2,如果是机器方的话给予10分,如果是人方的话给予-10分;
判断是否能成活2,如果是机器方的话给予5分,如果是人方的话给予-5分;
判断是否能成死2,如果是机器方的话给予3分,如果是人方的话给予-3分。

实际上对当前的局面按照上面的规则的顺序进行比较,如果满足某一条规则的话,就给该局面打分并保存,然后退出规则的匹配。

注意这里的规则是根据一般的下棋规律的一个总结,在实际运行的时候,用户可以添加规则和对评分机制加以修正。

三、胜负判断
实际上,是根据当前最后一个落子的情况来判断胜负的。

实际上需要从四个位置判断,以该子为出发点的水平,竖直和两条分别为45度角和135度角的线,目的是看在这四个方向是否最后落子的一方构成连续五个的棋子,如果是的话,就表示该盘棋局已经分出胜负。

具体见下面的图示:
四、搜索算法实现描述
注意下面的核心的算法中的变量currentBoardSituation,表示当前机器最新的盘面情况, CountList表示第一层子节点可以选择的较好的盘面的集合。

核心的算法如下:
void MainDealFunction()
{
value=-MAXINT; //对初始根节点的value赋值
CalSeveralGoodPlace(currentBoardSituation,CountList);
//该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况,可以根据实际的得分情况选取分数比较高的几个盘面,也就是说在第一层节点选择的时候采用贪婪算法,直接找出相对分数比较高的几个形成第一层节点,目的是为了提高搜索速度和防止堆栈溢出。

pos=CountList.GetHeadPosition();
CBoardSituation*pBoard;
for(i=0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard-> value,max);
//取value和pBoard-> value中大的赋给根节点
}
for(i=0;ivalue)
//找出那一个得到最高分的盘面
{
currentBoardSituation=pBoard;
PlayerMode=min; //当前下子方改为人
Break;
}
}
其中对于Search函数的表示如下:实际上核心的算法是一个剪枝过程,其中在这个搜索过程中相关的四个参数为:(1)当前棋局情况;(2)当前的下子方,可以是机器(max)或者是人(min);(3)父节点的值oldValue;(4)当前的搜索深度depth。

double Search(CBoardSituation&
board,int mode,double oldvalue,int depth)
{
CList m_DeepList;
if(deptholdvalue))== TRUE)
{
if(mode==max)
value=select(value,search(successor
Board,min,value,depth+1),max);
else
value=select(value,search(successor
Board,max,value,depth+1),min);
}
return value;
}
else
{
if ( goal(board) <> 0)
//这里goal(board) <> 0表示已经可以分出胜负
return goal(board);
else
return evlation(board);
}
}
注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负,而evlation(board)是对当前的盘面从机器的角度进行打分。

下面是Select函数的介绍,这个函数的主要目的是根据PlayerMode情况,即是机器还是用户来返回节点的应有的值。

double Select(double a,double b,int mode)
{
if(a> b &&mode==max)&brvbar;&brvbar; (a < b &&mode==min)
return a;
else
return b;
}
五、小结
在Windows操作系统下,用VC++实现了这个人机对战的五子棋程序。

和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比,在智力上和时间有效性上都要好于这些程序。

同时所讨论的方法和设计过程为用户设计其他的游戏(如象棋和围棋等)提供了一个参考。

相关文档
最新文档