【国象AI】评估函数(三)StockFish 评估概览

简要介绍

国际象棋基本常见的几种评估有Material子力、Space空间、Mobility机动性、Tempo着法、Threat威胁、Shape形状、Motif图案等,而在具体的确定的时候还有很多不同的表现形式。一个棋子的移动往往是影响多个评价指标之后得到的综合结果。但是往往这些的计算不会严格按照这样的框架,比方在Stockfish中这些类型的划分就没有那么的死板。
评估和棋盘表示关系非常的大,棋盘的结构(和对棋盘结构的理解)非常影响写评估的手感。而且对模板的数量应用可以减少很多的工作量。这点相比起来Stockfish就做的非常的优秀(结构真的非常的漂亮但是有的时候也会找不到要用的东西)。
比如说取一个函数。

  template<Tracing T>  template<Color Us>
  Score Evaluation<T>::evaluate_space() {
    const Color Them = (Us == WHITE ? BLACK : WHITE);
    const Bitboard SpaceMask =
      Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
                  : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
    //…

可以通过模板和这些参数的设定,来减少对我方颜色棋子的重复判断。而且变量名非常的清楚。

技巧

首先这里用到的一个概念是局势。对于开局/中局和残局,往往有不同的评价。比方说,往往在残局兵由于可以升变作用会更加明显;在中局的时候王非常容易受到攻击所以一些防御措施,比如王前面有兵遮挡(常见的一个防御方式)给的加分会比较多,而在残局的情况下由于王需要积极的行动作为战斗力,这种加分就几乎不可见。
在这里,主要是用非兵的棋子总的子力来体现局面(中局/残局),这两者之间是线性插值。局势的存储用32位,前16和后16分别记录中局/残局的情况。这样通过一次加减可以完成同时对中局/残局评价的处理。这样记录可能由于借位等造成前面的存储有一的偏差,但是在整个评估中影响不大。

constexpr Score make_score(int mg, int eg) {
  return Score((int)((unsigned int)eg << 16) + mg);
}

关于藐视因子,藐视因子在这里用的是0,它在评估函数中的作用直观理解是直接加在最后的评价中,而实际应用的话他会让评价提前退出:当局面完成Material、Imbalance、Pawn的评价之后,会判断当这个值是不是超出一个LazyThreadhold,如果超出的话会提前退出。因为在这种情况下评估判断已经做得足够好而不再做细节的搜索。这个带来的影响就是,在双方的差距非常明显的时候,AI的评估会做的比较简单——只保留关键的影响比较大的因子,或许从某种程度上是认为此刻加深搜索的深度比评估包含更多的细节更加重要。
此外该引擎中还用到了大量的Hash表的加速。兵和其他棋子的hash表区别存放。而且比较奇怪的是这一部分的种子是人工给定的不知道是不是经过测试得出的结果。但是这一部分我们还有待完善。
还有一些基本的功能是在评估外的。比如SEE,可以在搜索树生成的时候就减少一些不必要的送子/交换。但不在评估的模块所以不做详细说明。

具体说明

接下来分类对于每一类评估所做的事情进行说明。

Material

Material是子力价值,这一部分的价值应该是直接存在棋盘内,每次移动的时候就做加减的更新,而不需要不断的扫棋盘重新计算。它对于每个棋子给定了在不同位置上的价值(不变的基础价值和棋盘各个位置的价值)。对于象和马这种攻击范围和位置关系非常大的棋子,各个位置上的变化相对就会比较大。
然后Material上还有一块就是,对于残局的判断。在人类学棋的时候残局也是单独会拎出来训练的一块,在这种情况下的子力评价无法像之前那样做判断,就好像比较经典的剩单兵的情况,能否升变和双方王的位置关系非常的密切,而这种胜负/平手的评价没有办法用和之前一样的确定方法。此外还有如果棋子少的话P的数量和位置能够起到的影响是和之前完全不一样的体系了。而对于剩下BB/BN/NN的情况,也需要单独的考虑。

Imbalance

Imbalance,考虑的主要是棋子数量的相互影响。虽然这个很直觉的例子就是比如两只马的作用会比单独相加要大。但是这个他就比较夸张了……把我方棋子和对方棋子的数量相当于是种类对种类建立起来关系。

具体棋子

Pawn,兵的评估,这一部分涉及的孤兵、叠兵、落后兵的惩罚,连通的兵的奖励,和其他棋子的关系来说在这部分主要考虑到了兵对王的保护和对对方王的威胁(兵风暴,兵向王的移动可能带来很大的威胁)。
接下来的几个计算是对各种棋子的计算,同时更新被双方棋子威胁的位置。都要计算的是对王的保护,其他对于不同的棋子有一些不同的值。比如Knight和Bishop会考虑被我们的兵保护或是在兵后面的加分,Bishop会有能掌控长距离的斜线的加分,Rook会考虑占据通路半通路等,而Queen会考虑到牵制半牵制等危险的情况。

Mobility

Mobility的计算和之前的子力计算同时进行,计算的是能够安全移动到的位置。这个的定义是与棋子类型和移动到的位置有关的二维数组。

King safety

King safety计算王的安全性。根据王周围一圈被威胁的情况来确定该值。

Threats

Threats用来计算威胁的情况。根据被什么棋子攻击、被什么棋子保护之类的信息,来确定具体数值。

Passed pawns

Passed pawns用来计算兵的运动是否受到阻碍。

Space

Space是只用于优化开局的一个函数(参考之前对局面的定义),是根据在兵后面的安全的棋子的数量给出的一个评价(这个有点难说清……这个值也经常是0)。

猜你喜欢

转载自blog.csdn.net/birdy_/article/details/80567619