下棋的程序,主要难点在“人机对战”,也就是机器有多聪明,下棋水平(AI)高不高。 不同的棋类,棋盘、棋子、规则都各不相同。但制作人机大战的思路有许多共同的特点。
1.局面估值 根据当前的棋局和“轮到谁走下一步棋”对当前局面进行估算,得到一个或少数几个整数(小数也无防)。一般是4个整数合成(加法)一个整数,这4个整数是: 我攻+我防+敌攻+敌防。即对自己有利的 避开对自己有害的 避开对敌人有利的 对敌人有害的。(感谢咙想酒甜 446828992)
2.搜索
2.1 单步搜索。根据当前棋局,算出我方最可能下的一步棋几种情况,然后计算每一种可能下子后的局面估值,哪个局势对我方最有利就下哪一步。
2.2 多步搜索。在内存中演绎(模拟)我方走一步(记为第1步),敌方走一步(记为第2步),我方再走一步(记为第3步)……模拟n步后,每一步都取对己方(有时我是己方,有时敌是己方)最有利的一步,最终算出第1步应该走哪步。
搜索往往是核心,计算量非常大,所以一般很难搜得深。为了加速搜索速度,会引入许多剪枝算法,常用的是Alpha-Beta剪枝。
3.开局库 游戏开始就使用开局库,如果局面命中开局库,就按库来走子,省掉了大量搜索,开局库往往是经验的积累,好的开局库能很大的提高棋力(棋力也叫博弈软件的AI水平)
4.残局库 残局库通常收录的是必胜的棋局,只要命中(可能为全局命中或局部命中,具体情况具体分析)照着走就能胜出。对有些棋类可能残局库难以适用。
5.开局、搜索、残局的关系 开局使用开局库,直到超出库的范围。然后每次都搜索残局库(性能优化方面再依具体情况而定),命中则按残局库走,未命中则搜索。
6.学习功能 学习功能主要是对残局库、开局库的丰富,但也可以用在局面估值参数的调优。
6.1残局库的丰富 (前面说了残局库的每一个都是必胜局面)
如果当前从当前局面出发总能进入残局库,则当前局面为必胜局面,添加入残局库。实时添加。
6.2开局库的丰富
通过事后以大量的数据进行分析,统计出超出开局库后的第1步(仅1步)的多种不同走法的胜败概率,从而将胜率较高的一步添加入开局库。非实时添加。
6.3 局面估值参数的调优
在对参数进行调整前后,两个软件对战1000局,根据结果决定是否采纳新的参数。参数多时,有必要设计一套调整算法,只要有时间就让机器跑,跑得多了参数也就趋于最优。理论上是这样的。
严格来讲6.2和6.3不算学习功能,不管算不算学习功能,它们都是很有意义的。
如果需要对软件的棋力分档设置(如初级、中级、高级),简单的做法是设置搜索的深度,初级搜得浅,高级深。
由于搜索是一棵树,每一个节点都可能有许多子节点,这棵树的节点很多,所以需要优化,一般的优化是剪枝,也往往会使用多种技术综合进行剪枝,所以出现了搜索相同的深度,不同的棋局所需要的时间大不相同。考虑到玩家的等候时间不宜过长,所以需要在搜索的同时控制时间。个人认为让用户等6秒到10秒,还是比较正常的,两个人的下棋,也差不多是这个时间。当然有时需要的时间极短。
让两个软件相互PK,对AI的改进有重大的作用。需要对两个软件进行对接,从代码对接(两份代码融为一份,类似双核CPU),耦合性太高,通用性太低。从界面对接,耦合性和通用性中等,操作繁琐,通信效率低(想象一下,PK1000局所花的时间)。理想的情况是网络对接。需要一套公共的协议,然后只要实现了该协议的任何2个软件就可以进行PK。
本文根据聊天记录整理,主要是当作自己的笔录。当然也欢迎各位朋友评论和指正。