• JavaScript中国象棋程序(8)


    “JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序。这是教程的第8节。

    程序的最终效果点击这里查看

    这一系列共有9个部分:

    0、JavaScript中国象棋程序(0)- 前言

    在这最后一节,我们的主要工作是使用开局库、对根节点的搜索分离出来、以及引入PVS(Principal Variation Search)主要变例搜索。

    8.1、开局库

    这一节我们引入book.js文件。该文件中定义了一个二维数组BOOK_DAT。这个数组就是开局库,保存的数据格式如下:

    [lock, mv, vl]

    其中,lock = zobristLock >>> 1(无符号右移1位,高位补0)

    mv是步骤

    vl是权重(随机选择走法的几率,仅当两个相同的lock有不同的mv时,vl的值才有意义,这是为了实现走棋的随机性)。

    开局库是按照lock排序的,因此可以用二分查找。找到一项以后,把它前后lock相同的所有项都取出,从中随机选择一个mv。

    压缩开局库的容量,所有对称的局面只用一项,所以当一个局面在BOOK_DAT中找不到时,还应该试一下它的对称局面是否在BOOK_DAT中。

    8.2、对根节点的特殊处理

    现在由于开局库的加入,开局程序的走法具有了一定的随机性。但如果是开局库中没有的局面,程序的走法依然是固定不变的。我们在根节点处,对搜索得到的分值,做小范围的浮动,以此实现走法的随机性。

    vlBest += Math.floor(Math.random() * RANDOMNESS) - Math.floor(Math.random() * RANDOMNESS);

    其中,RANDOMNESS = 8。新的分值会在区间(vlBest - 8, vlBest + 8 )浮动。

    我们把对根节点的搜索分离出来,这有以下好处:

    1、更方便实现走法的随机性

    2、没有必要尝试Beta截断(根节点处Beta正无穷);

    3、省略了检查重复局面、获取置换表、空步裁剪等步骤。

    8.3、PVS主要变例搜索

    经过前面的工作,走法已经得到了很好的排序,好的走法会先被搜索。这是PVS的基础。

     a                                                                                 图b

    假设第一个走法是最好的走法,没有引发剪枝,A点的搜索区间为(0, 100),走法1得到估值30。由于30  > 0,所以A点的alpha变为30,以后的搜索区间变为(30, 100),所以B2点的搜索区间为(-100, -30)。

    可以进一步大胆地考虑,假设第1个走法就是最好的走法,那么后面走法得到的估值不会落在区间(30, 100)。所以从A点的第2个走法开始,要做的就是验证这种假设,搜索区间为(30, 31)。由于搜索区间很小,搜索速度会很快。返回值vl有3种情况。

    1)、vl <= 30。说明走法不比第1个走法好,假设成立。

    2)、vl >= 100。返回值比A点的原有搜索边界beta还大,应该剪枝,假设成立。

    3)、30 < vl < 100。走法比第1个走法好,假设不成立。

     3种情况时,走法不成立,应该对该走法重新以(30, 100)区间进行搜索。如果得到40,则该走法就是最好的走法,后续搜索又对该走法进行假设验证,区间为(40, 41)。

    8.4、长将判负策略

    程序会调用repStatus函数,判断局面是否出现重复,以及长将,这在第6节已经介绍。如果出现长将,会得到-BAN_VALUE(其中,BAN_VALUE = MATE_VALUE - 100),再根据杀棋步数做调整。但是由于长将判负并不是对某个单纯局面的评分,而是跟路线有关的,把这个分值直接存入置换表就不太合适了。

    我们的解决办法就是:获取置换表时把“利用长将判负策略搜索到的局面”过滤掉。如果某个局面分值在WIN_VALUE(MATE_VALUE - 200)和BAN_VALUE之间,那么这个局面就是“利用长将判负策略搜索到的局面”。如果是通过repStatus函数得到了和棋的分值,会同样被过滤掉。

    我们仍旧把“利用长将判负策略搜索到的局面”记录到置换表,因为这些局面提供的最佳走法是有启发价值的。反过来说,如果“利用长将判负策略搜索到的局面”没有最佳走法,那么这种局面就没有必要记录到置换表了。

    8.5、核心代码说明

    本节的代码可以在 Github 下载,也可以直接clone

    git clone -b step-8 https://github.com/Royhoo/write-a-chinesechess-program

    Position中新增或修改的主要属性和方法:

    1)、bookMove()

    获取开局库中的走法。

    Search中新增或修改的主要属性和方法:

    1)、searchRoot(depth)

    对根节点的搜索。

  • 相关阅读:
    Linux系列教程-----Linux安装centos6.8
    laravel 常见操作
    git 拖下laravel 代码后报错 Warning: require(D:WWWlaravelootstrap/../vendor/autoload.php
    phpunit单元测试
    linux环境配置
    window 环境下在虚拟机上安装php环境
    第三方登录---微信(使用laravel插件)
    h5页面在ios机上禁止长按复制
    JS 中根据iframe子页面自动iframe高度
    关于JS解析编历JSON数组(含多维数组)
  • 原文地址:https://www.cnblogs.com/royhoo/p/6425912.html
Copyright © 2020-2023  润新知