六子棋培训讲义
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.2.1. 1. 2. 3. 4. 2.2.2. 1.
眠二(Sleep two) :XOO++++,在同一直线上的 2 颗同色棋子,符合“再下两手棋 只能形成眠四”的条件。 简单棋型识别算法简述 从左到右从上到下扫描找出第一个非空点。 以此点为中心分别在水平、垂直、左斜、右斜四个方向扫描棋型。 将以参与扫描的点标记为“已分析” 。 读取下一个非空点,如果该点未被分析,则转 1,否则转 4,直至所有的点都已被 分析。 横向扫描 从左到右从上到下扫描找出第一个点。
4. 5.
} 按照水平扫描棋型的方法分析该临时数组 标记扫描过的点
2.3. 评估系统
根据棋型识别所得的结果对当前棋局进行评估, 得到当前棋型的估值。 一般来讲估值越 大,局势对己方越有利。 2.3.1. 静态原始棋子位置得分 也就是位置得固有得分。其分值分布为:天元点分值最大,沿其四周分数依次递减,棋 盘四周分值最低。以 19*19 棋盘为例,我们可以建立静态棋子价值表。 int PosValue[19][19]= { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, {0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0}, {0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0}, {0,1,2,3,4,4,4,4,4,4,4,4,4,4,4,3,2,1,0}, {0,1,2,3,4,5,5,5,5,5,5,5,5,5,4,3,2,1,0}, {0,1,2,3,4,5,6,6,6,6,6,6,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,7,7,7,7,7,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,7,8,8,8,7,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,7,8,8,8,7,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,7,7,7,7,7,6,5,4,3,2,1,0}, {0,1,2,3,4,5,6,6,6,6,6,6,6,5,4,3,2,1,0}, {0,1,2,3,4,5,5,5,5,5,5,5,5,5,4,3,2,1,0}, {0,1,2,3,4,4,4,4,4,4,4,4,4,4,4,3,2,1,0}, {0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0}, {0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; 2.3.2. 对局势进行评估 在对棋局进行分析时,可以分为两种,第一种:棋盘得整体扫描。以 19 路棋盘为例, 需要计算 19+19=38 行阳线, (37-10)+(37-10)= 54 行阴线 ,共 92 路棋型得分。这里 92 路实际上可以划分为 4 个维度。即水平,竖直,左倾 45°,右倾 45°。第二种:以落子点 (或记录的 HP-3 棋型)为中心,向外延展 3 格检查(若研究对象是棋型,那么只需由向量 方向延展 3 格检查) 。 2.3.3. 潜力值的影响 有关潜力值得影响。 活二, 眠三, 如上面定义的, 看起来并不是很起眼。 他虽然不像 “四” 、 “五” ,那样具有非常直观的杀伤力,但是他往往是决定成败的关键因素。这里在一次提到 这个和 Connect(6,2,1)的特性是密不可分的。如果在活二的基础上沿其方向再连续增 添两子, 而其中一子又能与其它己方棋型形成一个威胁度的话, 那么就会马上获得胜利。 据 此我们可以设想构造一个形势评估函数(仅评估当前攻防趋势) ,如果一方没有活二,和一 些分布分散(可以用向量分析方法)的眠三,那么我们可以判断,此方目前进攻形式不佳, 只能加强防守,如果此时贸然冲四,可能导致顷刻告负。 相反,如果另一方,分布相对集 中的眠三,以及活二,那么我们可以考虑使用 VCF 战术。
bValue+=460*TypeCount[Black][SFOUR]; bValue+=350*TypeCount[Black][THREE]; bValue+=180*TypeCount[Black][MTHREE]; bValue+=150*TypeCount[Black][STHREE]; bValue+=150*TypeCount[Black][TWO]; bValue+=100*TypeCount[Black][MTWO]; bValue+=10*TypeCount[Black][STWO]; wValue+=10000*TypeCount[White][SIX]; wValue+=1000*TypeCount[White][FIVE]; wValue+=900*TypeCount[White][FOUR]; wValue+=500*TypeCount[White][SFIVE]; wValue+=460*TypeCount[White][SFOUR]; wValue+=350*TypeCount[White][THREE]; wValue+=180*TypeCount[White][MTHREE]; wValue+=150*TypeCount[White][STHREE]; wValue+=150*TypeCount[White][TWO]; wValue+=100*TypeCount[White][MTWO]; wValue+=10*TypeCount[White][STWO]; if(nType==White) { return wValue – 1.5*bValue; } else { return bValue – 1.5*wValue; } }
const int Black=0,White=1,Empty=255;
int ChessBoard[19][19];
2.2. 棋型识别
以 19*19 的二位整型数组作为输入,通过对棋盘 4 个维度(水平,竖直,左倾 45°, 右倾 45°)的扫描,统计处各种棋形的数量。 棋型一般包括: 六连 (Continuous six) : +OOOOOO+, 在棋盘的纵向、 横向或斜向的任意一条线上, 形成的 6 颗同色棋子相连。 长连(Continuous long) :+OOOOOOO+,在棋盘的纵向、横向或斜向的任意一条线 上,形成的 7 颗或 7 颗以上同色棋子相连。 六连或长连是六字获胜的必要条件。 活五(Active five) :+OOOOO+,在同一直线上的 5 颗同色棋子,符合“对方必须 用两手棋才能挡住”的条件。挡住是指不让另一方形成六连或长连。 眠五(Sleep five) :XOOOOO+,在同一直线上的 5 颗同色棋子,符合“对方用一手 棋就能挡住”的条件。 活四(Active four) :++OOOO++,在同一直线上的 4 颗同色棋子,符合“对方必须 用两手棋才能挡住”的条件。 眠四(Sleep four) :XOOOO++,在同一直线上的 4 颗同色棋子,符合“对方用一手 棋就能挡住”的条件。 活三(Active three) :+++OOO+++,在同一直线上的 3 颗同色棋子,符合“再下一 手棋就能活四”的条件。 朦胧三(Indistinct three) :X++O+OO+X,在同一直线上的 3 颗同色棋子,符合“再 下一手棋只能形成眠四,但如果再下两手棋的话就能形成活五”的条件。 眠三(Sleep three) :XOOO+++,在同一直线上的 3 颗同色棋子,符合“再下两手 棋也只能形成眠五”的条件。 活二(Active two) :++++OO++++,在同一直线上的 2 颗同色棋子,符合“再下两 手棋就能形成活四”的条件。
六子棋培训讲义
1. 规则简介
规则与五子棋非常相似, 除了第一次黑方下一颗子外, Hale Waihona Puke Baidu后黑白双方轮流每次各下两子, 先连成六子者获胜。
2. 程序架构
六子棋博弈程序和一般的博弈程序一样,一般包括一下几部分:
2.1. 棋盘表示
棋盘表示主要探讨的是使用什么数据结构来表示棋盘上的信息。 一般说来, 这与具体的 棋类知识密切相关。通常,用来描述棋盘及其上棋子信息的是一个二维数组。例如,对于六 子棋,我们可以用一个二维数组 ChessBoard[19][19]来表示棋盘,定义黑棋为 0;白棋为 1, 空为 0xFF。
以此点为中心分别向左右两个方向扩展, 得到棋型的 “相连边界” 和 “落子范围” , 如图所示。 3. 计算中心相连部分的长度。 4. 根据中心相连的长度判断棋型,并将以参与扫描的点标记为“已分析” 。 2.2.3. 其他方向扫描 我们可以将垂直、左斜、右斜方向的棋型扫描转换为水平方向的棋型扫描。以从左上到 右下方向扫描为例 1. 新建一个一维数组 int tempLine[19]。 2. 找出待扫描点所在左 45 度斜线的起始位置 //(y,x)为一行的起点 if (i < j) { y = 0; x = j - i; } else { x = 0; y = i - j; } 2. 3. 将该条斜线上的点复制到临时数组 tempLine 中 for ( k = 0; k < GRID_NUM; k++) { //防止越界 if (x + k >= GRID_NUM || y + k >= GRID_NUM) tempLine[k] = chessBoard[y+k][x+k]; break;
2.3.4. 权值与参数值的优化 评估函数的准确度直接影响着博弈程序的好坏, 一个准确度差的博弈程序, 即使搜索深 度再深, 也很难提高棋力, 甚至还会离精确值越来越远。 一般我们会对参数值进行人工调整。 从经验上我们就可以得知, 活四的价值要大于活三的价值, 多个眠三的价值可能都小于一个 活四的价值等等。将自己的这些猜测放入其中与机器反复对弈,然后改变参数,试验程序的 能力是增强还是削弱了。在经过多次实验后,找出一组性能较高的参数。手工调整的方法很 费时间。并且由于人同机器博弈时由于偏好、风格、疲劳程度以及博弈技术的限制,准确的 分辨两组参数孰优孰劣并不容易。这时候,采用程序来辅助确定参数就有一定的必要了。下 面介绍几种通过程序优化参数的方法: a. 爬山法 (Hill-Climbing).类似于交手法, 每次对权重作很小的改变, 测试改变后的表现, 仅当成绩提高时才采纳这个改变, 需要重复很多次.这个方法看上去很慢, 并且只能找到 “局 部最优”的组合(即评价可能很差,但是任何很小的改变都会使评价更差)。 b. 模拟退火法(Simulated Annealing)。类似于爬山法,也是对权重做出改变来提高成绩 的。但是如果改变没有提高成绩,有时候(随机地,给定一个几率)也采纳改变,试图跳出全 局最优。这个方法需要给定一些几率,从几率高、梯度大的条件开始,然后逐渐减小。模拟 退火法比爬山法更慢,但是最终可能得到比较好的值。 c.遗传算法(Genetic algorithms) 。爬山法和模拟退火通过逐渐的改变参数来逼近一组 较好的参数。而遗传算法则同时维护着几组较好的参数。通过向其中添加一组新参数,通常 是将几组老参数中选出的值组合在一起作一点变化。 然后同几组老的参数比较孰优孰劣。 将 最差的一组从中去除。 这里面较重要的操作是交叉和变异操作。 交叉通过随机交换父代个体 的信息来继承已有参数中的优良内容。 变异则通过随机改变个体中的基因而增加种群的多样 性,避免优化的因局部震荡而失败。这一寻优算法由 J. Holland 于 1975 年提出。因其模仿 生物的遗传机制(包括染色体的复制,交叉,变异等操作)而得名。 详细内容请参考“计算机博弈培训班教材” 。 2.3.5. 简单评估函数实例 简单估值参考: 棋型 六连 活五 眠五 活四 眠四 活三 己方 10000 1000 500 900 460 350 棋型 朦胧三 眠三 活二 朦胧二 眠二 分值 180 150 150 100 10
///<summary> /// 简单估值函数 /// 获取nType方的评估值 ///<summary/> int GetEvaluatedValue(int chessBoard[][GRID_NUM],int nType) { int wValue=0,bValue=0; scan(chessBoard); //计算估值 bValue+=10000*TypeCount[Black][SIX]; bValue+=1000*TypeCount[Black][FIVE]; bValue+=900*TypeCount[Black][FOUR]; bValue+=500*TypeCount[Black][SFIVE];