
五子棋AI算法的改进方法.docx
10页又是本人一份人工智能作业……首先道歉,从Word贴到Livewrter,好多格式没了,也没 做代码高亮……大家凑活着看……想做个好的人机对弈的五子棋,可以说需要考虑的问题还 是很多的,我们将制作拥有强大AI五子棋的过程分为十四步,让我来步步介绍第一步,了解禁手规则做一个五子棋的程序,自然对五子棋需要有足够的了解,现在默认大家现在和我研究五子棋 之前了解是一样多的以这个为基础,介绍多数人不大熟悉的方面五子棋的规则实际上有 两种:有禁手和无禁手由于无禁手的规则比较简单,因此被更多人所接受其实,对于专 业下五子棋的人来说,有禁手才是规则所以,这里先对''有禁手〃进行一下简单介绍:五子棋中''先手必胜〃已经得到了论证,类似“花月定式〃和''浦月定式〃,很多先手必胜下法虽 然需要大量的记忆,但高手确能做到必胜所以五子棋的规则进行了优化,得到了 ''有禁手〃 五子棋五子棋中,黑棋必然先行因此''有禁手”五子棋竞技中对黑棋有以下'禁手〃限制:''三 三禁〃:黑棋下子位置同时形成两个以上的三; ''四四禁〃:黑棋下子位置同时形成两个以上的 四; ''长连禁〃:六子以上的黑棋连成一线黑棋如下出''禁手''则马上输掉棋局。
不过如果''连 五〃与''禁手〃同时出现这时''禁手〃是无效的所以对于黑棋只有冲四活三(后面会有解释) 是无解局面反观白棋则多了一种获胜方式,那就是逼迫黑棋必定要下在禁点为了迎合所有玩家,五子棋自然需要做出两个版本,或者是可以进行禁手上的控制第二步,实现游戏界面这里,我制作了一个简单的界面,但是,对于人机对弈来说,绝对够用和很多网上的精美 界面相比,我的界面也许略显粗糙,但,开发速度较高,仅用了不到半天时间下面我们简 单看下界面的做法界面我采用了 WPF,表现层和逻辑层完全分开,前台基本可以通过拖拽完成布局,这里就 不做过多介绍根据界面截图简单介绍1处实际上市两个渐变Label的拼接,2、3是两个label, 4、5实际上是两个Butt on, 但是没有做事件响应通过按钮6、7、8、9的控制,修改label和Button的Content 属性也许有人会奇怪,为什么Button会丝毫看出不出有Button的影子,这里战友 whrxiao写过一个Style如下vStyle x:Key="Butt on Style1" Tar getType="{x:Type Butto n}">
界面逻辑上,将是否开始、是否禁手和是否电脑先行 作为两个全局变量的布尔型值,通过设置和判断bool型值进行逻辑上的控制中间的棋盘 是个can vas, —个15*15的Grid放满Butt on并将每个Butt on应用Stylel开始时候 透明度设为0也就是根本看不到,在下棋的时候改变Button的背景和透明度,实现落子 的效果,因为Grid的位置关系,所以可看起来好像是下在横竖的交线处第三步,进行输赢判断:因为规则不同,''无禁手〃和''有禁手〃的输赢判断自然不同先看无禁手:这个比较简单,遍 历每个位置,然后从这个位置开始,分别判断它的四个方向:即横、竖、左上到右下、左下 到右上每个方向从中间点开始,往两边数连子数,然后将两个方向的连字数加和再加一(中 间的棋子)如果得到大于等于5,那么就说明下子方赢棋对于有禁手的五子棋,输赢判断还需要判断禁手,禁手的判定较为复杂将待判断点放入黑 棋子然后搜索待判断点周边棋盘;还原棋盘;利用搜索结果依次对各方向进行分析,判断 黑棋放入后所产生的棋型是否形成长连或形成某种四连或三连的的棋型若形成长连,判定 为禁手,返回长连禁手标识若形成某种四连或三连的棋型,该棋型统计数加1,再对下一 个方向进行判断,直到各个方向分析结束。
若四连棋型或三连棋型的统计数大于1,则返回 为禁手其余情况返回非禁手第四步:构造棋型估分''有禁手〃规则比较复杂,涉及到比较多下棋方面的技巧,而且对算法的思路没有丝毫影响, 所以下面我们主要考虑无禁手规则下的AI设计若设计好无禁手AI,只需要让AI执黑时 坚决不下到禁手点,就可以很快构造有禁手的AI虽然这种方式没有利用有禁手规则下的 技巧,但这些技巧只需要修改下面所讲到的估分函数即可我们可以将五子棋的连珠可以分为以下几种:成5:即构成五子连珠活4:即构成两边均不被拦截的四子连珠死4 :一边被拦截的四子连珠活3:两边均不被拦截的三字连珠死3: 一边被拦截的三字连珠活2:两边均不被拦截的二子连珠死2: 一边被拦截的二子连珠单子:四周无相连棋子根据五子棋的技巧,可以将五子棋的棋型用连珠进行分类,分类过后我们按照威力给每种棋 型打分因为五子棋一次只落一子,因此很容易理解,双活三和三活三的威力是一样的,类 似情况不多做解释程序中,我以100分为满分,对棋型进行了以下打分:成5, 100分活4、双死4、死4活3, 90分双活3, 80分死3活3, 70分死4, 60分活3, 50分双活2, 40分死3, 30分活2, 20分死2, 10分单子0分有了估分方法,就有了五子棋AI的基础,接下来就是一些博弈的方法了。
第五步:得到位置估分AI单纯应用棋谱以及对五子棋当前局势的分析,对每步进行估分,程序中做如下工作:将每个 位置进行分析,假设AI落子在该位置,用以上打分规则为AI打分,并将得到的分数加一 然后,假设玩家落子在该点,为玩家打分,然后将所有的分值汇总取最高分作为这个位置 的估分,接下来就是取分数最高的位置下棋了''位置估分〃,下棋的时候,既可以考虑到自 己攻击对手,又能考虑到对对手的防御,可以说,很多时候可以顶上考虑两步的AI'作实 验,从网上下载了一个用博弈做的AI,和''位置估分〃对下,结果是一胜一负' 谁先子,谁 赢得胜利'而且一步估分毫无疑问是最快的,即使遍历所有位置,也能很快的做出决策'第六步:应用博弈树,提高AI智能做五子棋的博弈,自然会用到博弈树,这里我说下自己的思路'在对弈中,根据下一步由谁 来走,AI对任何一个局面根据前面估分方法给出一个分数,我们把这个估分方法汇总成一个 评估函数,并返回分值'据此来选择下一步的走法'由于人和AI是轮流落子,可以将人的 估分也算入,并将前面加负号那么,估值越大表明对AI越有利,估分越小则表明对AI 越不利'那么每次AI选择都是从它可能的走法树的某层节点,返回评估值中最大点。
而用 户总是从走法树的某层节点中选择最小点,从而形成一棵极大极小搜索树,然后根据深度优 先搜索,可以最后得到固定搜索深度下的一个最好的走法我做了下试验,单纯应用博弈树, 可以在100ms之内让AI考虑完整的两步,由于组合爆炸,当需要考虑三步的时候,就需 要6s左右,4步就需要1分钟拿两步来和一步估分作比较,虽然比较慢,但是确实有了 一定智能第七步:考虑层数,提高AI智能上面的设计对于返回值是统一处理的,但是,层数是个很重要的信息■因为下棋时如果能2步 获胜,不应选择4步获胜对于输的棋型层数就更重要,AI必须尽可能拖延输的时间,就有 更大的可能让AI化险为夷这样,可以通过设置一个dep值深度约浅,dep越大,用 dep和得到的得分相乘,得到搜索节点的得分,再进行以上算法,进一步提高AI的智能第八步:应用a B剪枝,提高AI速度在搜索博弈树的过程中,实际上搜索有很多点是多余的,例如下图图中,方形框节点是该AI走,圆形框节点是该人走■比如C节点,它需要从E和F当中选取 最大的值目前已经得出E为2,当搜索F节点时,因为F是人走的节点,那么F需要从K L M中选取最小的,因为K已经是1也就是说F< = 1,那么L,M就不需要搜索,因此就 发生了 a剪枝。
然后看A节点,该人走了,需要从C和D中选取最小值,因为C节点是2, 而G是7,那么D至少是7因此,D的其他节点不必再考虑,就发生如上图所示的B剪 枝总结上面规律,我们可以得到剪枝方法如下:当前为AI下棋节点:a剪枝:如果当前节点的值不比父节点的前兄弟节点的大值大,则舍弃此节点B剪枝:如果当前节点子节点的值不比当前节点的前兄弟节点中的最小值小,则舍弃该子节 点和该子节点的所有后兄弟节点当前为用户下棋节点:a剪枝:如果当前节点的某子节点的值不比当前节点的前兄弟节点中的最大值尢则舍弃该 子节点和该子节点的所有后兄弟节点B剪枝:如果当前节点的子节点的值不比当前的父节点的前兄弟节点中的最小值小则舍弃此 节点经过a-B剪枝,可以极大的减少搜索的数量,很多时候,能把几十亿的搜索数量,缩小到 几亿,那么,就可以把搜索深度增1第九步:应用下棋范围,提高AI速度当前节点的子节点的数量和排列顺序对于搜索的速度起着至关重要的影响根据五子棋的特 点,可以产生一个棋面搜索范围记录当前棋面所有棋子的最左最右最上最下点构成的矩形, 我们认为下一步棋的位置不会脱离这个框3步以上这样在棋子较少的时候,搜索节点的 数量大大减少。
可以将AI的速度提高一倍左右第十步:利用棋型得分,提高AI速度因为每种下法都对应一种得分,所以,可以每次只考虑当前得分前十的节点进行下一步搜索, 大大减少了搜索范围,可以进一步增加搜索的深度第十一步:利用置换表,提高AI速度我们一般用递归的方法实现博弈树,但是,递归的效率是低的,而且很明显,有很多重复搜 索的节点,所以,我们可以用一个表,记录下所有搜索过节点的情况,然后只要遇到搜索到 的节点,就可以直接得到结果置于这个''表〃是什么,就是一个置换表,利用Zobrist算法, 进行Hash处理,使在表中查找的时间大大缩短,这样AI的速度又能提高一个数量级第十二步:利用多线程,提高AI速度我们其实可以利用多核技术,利用多个线程,让算法实现并行计算,提高AI的速度我们 在第一层用一个线程分配器把第二层的候选节点分配给多个线程z每个线程包含着从第二层 一个候选节点开始的搜索,然后等所有线程结束后,将所有线程的结果进行汇总,选出最大 值并行的程序,可以将速度提高一倍左右第十三步:利用随机化算法,让确定方法不能必胜由于AI算法的固定性,所以一担玩家一次获胜,按照相同的走法,必然会再次获胜但除 了必杀招或者必防招,一个局面很多时候没有绝对最好的走法。
而是有一些都不错的走法,那 么可以把这些评分差不多走法汇集起来,然后随机选择它们中的一种走法,避免AI的走法的 固定•这样最简单的方法避免固定方法AI必输第十四步:让AI自学习,不再同一个地方犯错上面的算法还没有自学习的能力,这样AI在下棋时还可能会重蹈覆辙因此在每盘棋结束时。
