中国象棋评估函数建模

  一.简介:

    最近在做一个lua版的象棋(使用lua也没有考虑性能的问题,主要是想练习一下lua的使用),在象棋的PVE模式玩法中,AI的落子处理打算采用经典的alpha-beta算法(之后的博客会详细记录),采用这种算法的棋类游戏AI的核心是对象棋局面的评估(打分),以便AI能自己计算每种走法得到的结果好坏,比较得到最好的走法,因此必须有一个局面的评估函数。这里记录一下评估函数的建模方案的学习总结。评估函数的建模方案来自于论文:《中国象棋计算机博弈数据结构与评估函数的研究和实现》,作者谢艳茹,读者可以自行搜索这篇论文。

    评估函数:在象棋、围棋、军旗等等棋类游戏中,一个走法的优劣不是由走法单一决定的,如中国象棋中走了一步炮7平4,这一步可能就将对方将死,也可能刚好将炮送给对方等等。所以评估某一步棋的好坏时,不是评估这步棋本身,而是评估在走完这步棋后形成的局面中双方的实力对比,这个实力对比和双方棋子数量及种类、棋子灵活度(可走范围)、棋子的威胁值(棋子下一步可以吃对方棋子)、棋子的保护值(棋子下一步可以走到的位置刚好是己方棋子,就保护了这个棋子)等等有关,评估函数就是根据当前棋盘上的这些情况给棋盘打分的函数,这个分数就是评估值。评估函数建模的目的就是建立一个根据棋盘棋子分布情况得到评估值的函数公式,接下来我们就可以根据这个数学模型(公式)写出我们的评估函数代码。

  二.评估函数建模

    1.评估函数和性能。参考:局面评估函数——简介(一) (xqbase.com)

      在建立评估函数模型前,有必要了解评估函数和性能的关系。评估函数模型并不是涉及到的变量越多越好(这种评估函数模型中运用到的各种变量和修正等我们可以称为知识),因为知识的增长会导致评估函数的计算时间变长,但是我们要直到AI的聪明程度不止和评估函数有关,还和搜索的深度(计算的步骤)有关,如果单个评估函数占用时间变长,相同时间内,搜索的深度就可能降低(可以这样理解,在不精简的情况下,在象棋中假如一个当前步骤我方棋子总共有35种走法,那么如果搜索深度为1时就需要评估35种棋盘;如果搜索深度为3时,即预测AI-玩家-AI可能的走法,就有35*35*35种棋盘需要评估,这是指数增长的运算量,因此当搜索深度足够深时,评估函数的运行时间的微小改变会被放大到不能忽视的地步,导致运行效率降低,要在相同时间内完成走法的选择,知识的增长就会导致搜索深度的降低)。所以在知识量增长到一定程度后,再增加知识量对AI的效率的提高就不再显著甚至负相关,所以有必要选择合适的知识量。

      这部分建模实际上是学习已有的建模方案然后对其的总结梳理,因此对知识量的选择上我不会下功夫,但是了解这部分内容我还是觉得很有必要。

    2.固定子力值。

      玩过象棋的人都知道,在下棋时,我们对有些棋子是格外在意的,如车、马、炮等,而有些棋子直到棋局的中后部分才开始动,我们开始是很少注意的,甚至会为了其他棋子增加可活动范围而主动送掉,如兵卒,这和我们对于棋子重要程度的评估有关。在象棋中,不同棋子的存在对棋局的影响是不一样的,我们用固定子力值来量化每一种棋子存在对棋局的影响,如将帅应该是无穷大的(一般使用一个远大于其他棋子子力值的值),而车是除将帅外最重要的棋子,所以数值也应该是最大的等。下面是论文中给出的各棋子的固定子力值:车950、马450、炮450、相200、士200、兵130、帅65536。最终的单方的子力值总分是将其所有棋子的子力值相加。

    3.棋子位置值

      在象棋中,一个棋子的存在会对局面造成影响,它的位置也同样对局面有影响,而且棋子在不同位置对局面的影响差别甚至可能非常大,如兵卒在未过河前和过河后、在地方九宫格附近和离九宫格较远时对对方的威胁程度就差别较大,因此不同棋子都有一个位置值得数组来评价其在不同位置对局面得影响。

      下面是棋子的位置值修正,我这里只采用兵的位置值修正,因为兵的位置对局势影响比较大,没有采用其他棋子的修正(主要为了精简算法,因为写这个项目的主要目的还是练习lua语言,而不是做AI或者人工智能之类的)

    4.棋子灵活度

      棋子的灵活度指棋子的可移动范围。在象棋中,棋子的可移动范围大小对于棋子能否发挥能力很重要,如蹩马腿、蹩象腿等操作都会降低对方棋子的灵活度。每一个棋子灵活度的计算就是计算棋子可走的格子数量,然后乘上这个棋子的灵活度系数(权重,每个棋子的重要程度不一样,所以提供一个系数对灵活度进行修正)。单方的棋子总灵活度是将所有棋子的灵活度相加。下面是各棋子的灵活度系数参考值:车7、马13、炮7、象1、士1、兵1.5、帅0。

    5.被威胁值

      被威胁值是指当前这个棋子处在多少个对方棋子的可移动位置上,也就是可能被吃,同样地,根据当前棋子的重要程度,它应该有一个权重修正,可以使用子力值进行修正。

    6.被保护值

      被保护值是指当前棋子处在多少个己方棋子地可移动位置上,也就是说这个棋子被吃后有多少个己方棋子能为自己“报仇”,这个值同样可以根据自身的子力值进行修正(同样被保护或者威胁,棋子的重要程度会对这种威胁或保护有影响)。

    7.棋盘范例

      在开局的过程中,有一些常走的棋盘范例(如当头炮,马先跳等),这些范例可以将棋盘保存下来,并保存一个主观赋予的评估值,然后在遇到相关棋盘时优先调取。也可以采用动态规划的思想,将已经计算过的棋盘评估值保存下来等。这一类的方法我都没有给予考虑。

    8.其他

  三.总结

    1.在二中我们讨论了几种评估棋盘的方式,实际求得的评估值可以将单方的这些量化数据求和或求差(如威胁值就有必要求差),然后将红黑方的单方评估值做差,即可得到一个数值作为评估值用于代表当前局面是优于红方还是黑方的,计算机可以据此作出着法的取舍;

    2.上面列出的评估项目还比较简要,评估所用的各种数值修正也仅作参考。这些数据往往是一个象棋游戏AI的核心部分,需要大量的实践让计算机自己修正或者人工修正,这就涉及到人工智能方面的内容了,所以我觉得没有必要深入。因为模型的粗糙,所以实际完成的AI很可能会出现智障行为,尽管如此,我也觉得可以了;

    3.我在模型中做了很多精简,主要考虑到做项目的目的是为了练习lua,没有必要在这方面耗费太多时间,因此这篇文章仅作为参考文章,也没有粘贴具体的实现代码,实际上就是我对于这部分内容理解的一个记录,所有内容仅供参考。如果您有兴趣了解更多关于中国象棋的知识,象棋巫师这个网站中的资料很不错,我也是主要看这个网站的资料理解象棋AI的算法实现的。

posted @ 2021-04-28 19:13  movin2333  阅读(1329)  评论(0编辑  收藏  举报