07 2012 档案
摘要:今天更新这一版本的程序,主要做了以下修改:
1、将常量放在一个单独类
2、用向量类代替棋盘类并更改记录方式
3、新的评价方法
4、根据棋型生成key
5、下子时只更新被改变的向量
6、实现双置换表
7、使用:历史表、alpha-beta剪裁、空步剪裁、冲棋延伸、主要变例搜索、迭代加深技术。不使用静态搜索等技术。
8、统计相关信息,以便计算置换表命中率、每秒搜索节点数、等等信息。
遗留问题:
1、棋型提取和评价函数。虽然找到了更优的棋型提取方法和评价函数,并且理论上速度可以达到与象棋引擎接近甚至更快的速度,但是代码还没写。
2、更好的剪裁方式。虽然现有的剪裁方式已经不错了,但是只要挖掘就还能找到更好的方法。就像代码中的棋盘剪裁更新一样。
接下来解释一下置换表和更新的这些部分的代码,以便下载源程序后更快的看完它。
阅读全文
摘要:实现静态搜索。
阅读全文
摘要:一、迭代加深
1、什么是迭代加深
所谓迭代加深,就是让alpha-beta剪裁运行深度1,然后运行深度1,2,然后运行深度1,2,3。
2、为什么进行迭代加深
…………
阅读全文
摘要:1、怎么让程序动起来?
程序是基于得分高低,来判断走哪步棋的。换句话说,我们评价走哪步时,总是考虑假如走这里会怎么样,假如走那里会怎么样,程序也是如此。只是实现起来没有那么简单。
2、alpha-beta剪裁是如何达到目的的?
这基于一个思想,如果局面评价是基于得分的,那么轮到谁走谁都要把这个得分弄得更高,程序如此,程序猜想对手走棋也是如此。所以,局面评价函数如果是:己方得分-对方得分,那么,这个分值越正,说明我们越接近胜利了,而这个分值越负,说明我们越接近输棋了。于是,我们总是寻找得分更高的走法,而得分低于一定程度(如对方成5)的走法,被剪裁(所谓剪裁掉,在程序中体现出来就是不继续扫描——exit for)。
3、如何实现这个递归函数?
设计递归的方式不止一种,但无疑都是要实现自己的目的。我们的目的是找到得分更高的走法,这里有这样几个关键点:
A、评价得分并比较
B、最高得分点需要记录
C、要交替查找可以走的点走棋
很明显,递归语句就在遍历点的循环中;最高得分的点可以用全局变量记录。接下来讨论一下评价函数放在哪里的问题:
阅读全文
摘要:1、为什么是72个?
72这个数,是五子棋上的“成棋向量”,只有72个方向能成5,而其他方向不够长度……这么说吧,横向15,纵向15,左下右上21,左上右下21,一共72。
2、如何得到这72个向量?如何记录它们?
得到这些向量很容易,可以硬编码,也可以循环遍历。我才用了循环遍历的方式,因为为了速度更快,我需要记录向量上的每个点,而不是计算它们。——当然,这里我没有进行测试,我感觉,一个14个元素的byte数组寻址速度不会很慢。
3、得到向量之后,如何评价?
我们使用一个数组,来记录当前向量上的全部子和空位,而后和模板数组进行比较,从而得到棋型信息。我们不会得到棋型的具体分值,最终综合棋型才得到得分。
实际的评价函数,是一个非常长的函数:
阅读全文
摘要:实现位棋盘和界面的代码。
阅读全文
摘要:说明引擎是什么,什么样的棋类可以开发引擎,实现一个引擎需要哪些技术,这些技术的作用是什么。
阅读全文
摘要:0、引言——认识“引擎”
1、实现界面和位棋盘
2、我的五子棋引擎如何评价局面
3、基石——超出边界的alpha-beta剪裁
4、接近人类的思考方式——迭代加深、棋盘剪裁、空招剪裁、冲棋延伸
5、重点问题重点分析——静态搜索
6、记住曾经的思考——置换表
7、做一个纯粹的思考者——将引擎和界面分离
阅读全文

浙公网安备 33010602011771号