您的位置:首页 > 大数据 > 人工智能

【五子棋AI】启发算法——VCF/VCT搜索

2013-10-09 21:45 791 查看
         今天把VCT改成了“全面VCT”,即可以解决全部VCT局面(当然,做棋不在其中,我也不打算写做棋的代码,但这不代表做棋不存在于软件当中,后面会介绍),然后灵光一闪,发现了PVS搜索时快速找到对方VCT/VCF的方法(之前只能快速找到自己的),理论上只需要十几行代码就可以了,具体实施还没做。

         前面几篇叙述的非常粗略,可以在学习写AI的时候有一些帮助作用,因为这些方面有很多资料可以参考,包括源码也比较容易找到。从这篇开始我会详细一些写,但也不会有太多源码,只是在必要的时候给出范例,因为我没有找到关于VCF/VCT/开局库的详细叙述(这里特指具体详尽的技术实现)和代码,所以走过很多弯路。例如,我开始写VCF函数的时候,使用了α—β搜索一样的代码,没有取得成功,即使我加入了一些新的参数,回头思考这个问题的时候,采用了类似min-max的搜索方法(我写了一组函数,包括attsearch,defsearch,attnextmove,defnextmove),因为很容易发现,当VCF不成立时,一定是进攻方没有进攻点了或者防守方胜利了。这一对函数很好的解决了VCF问题,然后当我写VCT函数时(实际上在这以后的一个月时间里我都在思考这个问题,这一个月是假期,所以不是业余时间,而是在思考,但从没写过代码),我遇到很多问题,就像什么情况下进攻方改堵防守方的成5点?以及这些问题引发的其他一些问题,开始时头昏脑涨,后来清醒了,终于写出了就像VCF一样的VCT的一组函数。

             但这组函数一直工作到上个月,我测试时发现了一个PVS的问题,接下来灵光一闪~~~~~~我去~~~~原来只需要在α—β搜索中做VCF/VCT就可以了,当初的失败确实是因为急躁、粗心和对这个函数的理解还是不到位引起的——我定义搜索失败的常量的时候出现了一些问题。于是我回头去写这个搜索函数,它确实正确的工作了,测试了很多VCF局面都很好,测试了几个VCT也很好,于是它就被搁置到今天。但是今天我测试时却发现很多VCT局面解不出来,于是回头查找问题,当确定搜索函数和VCF工作都没有问题时,把精力集中在VCT走法生成器上——当初我用我的意志决定了一些局面被认定为无进攻路线,修改了进攻方代码,解决了问题,但是后来又发现一些局面无解或错解(错解不该出现在全局VCT/VCF上,因为它们都是强制性走法。),于是又思考这个问题,一个多月的思考加上今天的整理起到了作用,也可能是灵光再闪…………结果是VCT函数竟然只比VCF走法生成器多13行代码,更令人汗颜的是我只是把上一个循环复制下来改了几个参数……

          

            上面说了很多,其实就是想发表一下码农中奖感言:得到他人的无私帮助,要有感恩的心,可能是我还不够虔诚,所以自己去做的时候才走了很多弯路;全局的观念,全面的思考,细致的研究,不断的探索,可以帮助我们解决问题,锯响就有末(高中班主任的口头禅)。下面说一下VCF:

VCF是一种“完全强制性胜利”,这种完全表现为对方没有任何走棋自主权——攻方走一步有1个或更多成5点,当然VCF路径上都是一个,达到二个或更多的时候已经VCF了。所以攻防走法生成器很简单:攻方走成5或下一步成5的点,迫使守方只能防守,即守方只能走成5点或防守。这句话可能不是很好理解,什么叫只能防守还走成五点或防守,意思是说,攻方不管守方棋型,只冲,这时候守方可能乘手达到成5,转守为攻;但守方没有主动进攻的权利。理解这个就好办了,VCF攻方生成逻辑就是:

if 对方已经成5 then return 失败

if 己方有成5点 then return 成功

生成全部下一步可成5棋型 return mvs

而守方逻辑就是:

if 对方已经成5 then return 失败

if 己方有成5点 then return 成功

生成对方全部成5点、必胜点 return mvs

很简单的代码,虽然不够优化,但是它工作的还是很好的,这得益于局面评价的前期剪裁,当然这种前期剪裁和上面几行代码中的前期剪裁都是基于“冲棋点搜索”、“走法分段排序”的优势——不用额外代码就能找到它们。

VCT也是一种“强制性胜利”,但这种胜利允许防守方进攻,我最初的代码不允许防守方进攻(包括现在发布的这个版本),所以是全局不全面VCT,而现在改为全局全面VCT。在逻辑上,进攻方也只走进攻招法,只不过进攻招法包括VCF进攻招法以外的招法——直到活2成活3的点(指通用意义上的活2活3,而不是冲棋点的活2活3),仅此而已,一旦加入了守方反攻点防守,那么会产生很多相关问题,逻辑复杂、代码效率降低。而守方是相对自由的,在攻方走VCF走法时当然是必防,但是更低的棋型时,完全可以反攻——只要这个棋型等于攻方最高进攻棋型。当然,如果详细分析去优化代码的话,还是大把的问题,无数的代码。现在我使用的是一个简化的版本,虽然它在逻辑上不是最优化的,但前面我提到局面评价函数有前期剪裁,虽然只是最基本的,但是也效率非常高,它足以抵消大部分由于未优化而产生的额外开销。VCT逻辑:

if 对方已经成5 then return 失败

if 己方有成5点 then return 成功

生成全部下一步可成5棋型+32 return mvs

而守方逻辑就是:

if 对方已经成5 then return 失败

if 己方有成5点 then return 成功

生成对方全部成5点、必胜点+守方必胜点 return mvs

两处红色的部分,就是VCT比VCF多的,所以VCF就是VCT的一个“强制性胜利”子集。同理也可以推断VC2是VCT的父集——它已经接近于整个走法集了。
今天对这个生成器作以修改,在攻方处加入了“半限制”形式的守方必胜走法,用于在一定条件下使得攻方不生成红色字体的+32棋型。

全部文章和源码整理完成,以后更新也会在下面地址:

http://www.vbdevelopers.org

http://www.softos.org
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  五子棋