JavaScript中国象棋程序(8) - 进一步优化
在这最后一节,我们的主要工作是使用开局库、对根节点的搜索分离出来、以及引入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)
对根节点的搜索。
JavaScript中国象棋程序(8) - 进一步优化的更多相关文章
- JavaScript中国象棋程序(0) - 前言
“JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.希望通过这个系列,我们对博弈程序的算法有一定的了解.同时,我们也将构建出一个不错的中国象棋程序 ...
- JavaScript中国象棋程序(1) - 界面设计
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第1节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(2) - 校验棋子走法
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(3) - 电脑自动走棋
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第3节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(4) - 极大极小搜索算法
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第4节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(5) - Alpha-Beta搜索
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第5节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(6) - 克服水平线效应、检查重复局面
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第6节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(7) - 置换表
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- 采用DTO和DAO对JDBC程序进行进一步优化
采用DTO和DAO对JDBC程序进行进一步优化 DTO:数据传输对象,主要用于远程调用等需要远程调用对象的地方DAO:数据访问对象,主要实现封装数据库的访问,通过它可以把数据库中的表转换成DTO类 引 ...
随机推荐
- Session监听事件的处理
设置Session监听 在web.xml文件中: <listener> <listener-class>cjq.login.listener.UpdateLogOutTime ...
- CentOS编译安装LNMP环境
这里是教大家如何在centos下利用源码编译安装LNMP环境. 工具/原料 centos服务器一台 自用电脑一台 准备篇 配置好IP.DNS .网关,确保使用远程连接工具能够连接服务器 配置防火墙,开 ...
- <!DOCTYPE> 声明 引发的错误
<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. 在写模板的时候,因为最近开始给每个文件添加注释,无意中将注释写在文件的第一行.导致页面 ...
- Java虚拟机——进度1
Java 虚拟机 一.Java虚拟机的基本结构 ①类加载子系统:从文件系统或者网络中加载Class信息,存放在方法区中. ②方法区中存放放进来的Class信息,也包括一些运行时常量池信息包 ...
- java--反射和注解
一.java.lang.reflect类 Class类 1.反射机制(Reflection):通过类创建对象, 2.反射机制提供了如下功能: 在运行时,判断任意一个对象所属的类 构造任意一个类的对 ...
- Objective-C中的Hello World
Objective-C在C语言的基础之上,加入了自己的一些独特的特性,而且在Objective-C中兼容C语言原有的用法.在Objective-C中,实现Hello World和C语言有一定的区别,如 ...
- Javascript 浮点运算问题分析与解决
分析 JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的. 浮点数的精度问题不是JavaScript特有的,因为有些小数 ...
- CocoaPods ReactiveCocoa 学习实践一 之 配置环境
1.安装CocoaPods 1.00.参考 CocoaPods 文档 1.01.是否已安装 which pod 1.1.升级gem命令 sudo gem update --system 1.2.切换C ...
- 【单调栈】hdu1506 Largest Rectangle in a Histogram
单调栈的介绍及一些基本性质 http://blog.csdn.net/liujian20150808/article/details/50752861 依次把矩形塞进单调栈,保持其单增,矩形中的元素是 ...
- java web几种开发模式(转)
Java Web开发方案有多种可供选择,这里列举一些经典的开发模式进行横向比较,为Java Web的开发模式选择提供参考.除此之外还有好多方案(如Tapestry和Wicket)并不了解,这里就不列举 ...