五子棋算法详解——解决方案之一这里讲述棋盘大小为10×10的人机对战五子棋实现方法,要看完整代码请看AS3做的五子棋1. 概述玩家每走一步,对于玩家和计算机,都根据获胜表对棋盘各个空棋位进行评分,每个位置的分数与下面这句话有关:该位置所在的每一种获胜组合中已经拥有的棋子数,然后对玩家和计算机产生的分数均衡,以判断计算机是进攻还是防守。
2. 数据结构10×10的数据,用来记录棋盘状态;两个获胜表([10][10][192]),也就是获胜组合,因为五个子一线则胜,不在一线上的五个子就不在一个组合中,对于10×10的棋盘获胜的组合有192种,下面将会详细说明,获胜表用来表示棋盘上的每个位置是否在玩家或计算机的获胜组合中;一个二维数组([2][192]),记录玩家与计算机在各种获胜组合中填入了多少棋子;两个10×10的数组,用来记录玩家与计算机在各个棋盘位置上的分数,分数高的将是计算机下一步的着法。
3. 计算获胜组合上图是一个10×10的五子棋棋盘,我们可以得出垂直方向上的获胜组合是10×6=60,同理,水平方向的获胜组合也是60,而两个倾斜方向上的获胜组合是(1+2+3+4+5)×2+6=36,即:60*2+36*2=192。
五子棋算法详解本文链接:/wwwanq/blog/item/66a9f4c5f390cdc338db497f.htm l4. 评分用两个数组存储每个棋位的分数,一个是计算机的,另一个是玩家的,表示该位置对于各方是最佳着法的肯定程度,对一个位置的评分就是:遍历该位置所在的每一种获胜组合,根据这个组合中已经拥有的己方棋子数1到4分别加不同分数,最后将这些所有的获胜组合所得出的分数相加就是该位置的分数,下图是对于黑方各棋位的评分(其中的1,2,3,4这几个值要根据实际需要来确定)。
5. 思路“五子棋”游戏的编程思路1、对棋盘上无子点进行分值评定,分值最高的点即为下一手棋的落点2、每一点有四个方向(横、竖、斜、斜)成五子可能,(4)3、每点在一个方向可以有五种呈五子排列形状(5)4、每点在每个方向有进攻和防守两个作用(2)5、具体量化确定如:每种情况,如:进攻:有1子(+1)、2子(+5)、三子(+25)防守:有1子(+1)、2子(+4)、三子(+16)(每次量化,如果五格中有对方子,该过程进攻分值为零,每次量化,如果五格中有己方子,该过程防守分值为零,)将每点的20次进攻和20次防守的分值相加,即为该点总分值按照这个思路编制的五子棋,有可能你自己都会输给机器当然,在具体编制过程时,还要考虑中心点分值稍高;已经有四子(对方和己方)的情况;六子情况;出界;对与最高分接近的点进行随机取点,以便程序具有随机性;以及已成五子等情况。
在以上程序编制完成后,还可考虑以下情况,以便对编程思路进行细加工,1,每个方向分值是否是进攻和防守分值的简单相加2,各个方向的分值是否是简单相加关系3,是否应考虑对具体形状的配合,给出组合分值4,以上都是固定直线型思路,是否应考虑蓄势待发情况,任何一种棋类游戏其关键是对当前棋局是否有正确的评分,评分越准确则电脑的AI越高。
五子棋游戏也是如此,但在打分之前,我们先扫描整个棋盘,把每个空位从八个方向上的棋型填入数组gStyle(2, 15, 15, 8, 2),其中第一个下标为1时表示黑棋,为2时表示白棋,第二和第三个下标表示(x,y)第四个下标表示8个方向,最后一个下标为1时表示棋子数,为2时表示空格数,如:gStyle(1,2,2,1,1)=3表示与坐标(2,2)在第1个方向上相邻的黑棋棋子数为3 gstyle(1,2,2,1,2)=4表示与坐标(2,2)在第1个方向上的最近的空格数为4在定义方向时,也应该注意一定的技巧,表示两个相反的方向的数应该差4,在程序中我是这样定义的:Const DIR_UP = 1Const DIR_UPRIGHT = 2Const DIR_RIGHT = 3Const DIR_RIGHTDOWN = 4Const DIR_DOWN = 5Const DIR_DOWNLEFT = 6Const DIR_LEFT = 7Const DIR_LEFTUP = 8这样我们前四个方向可以通过加四得到另一个方向的值。
如果你还是不太明白,请看下面的图:---------------------oo-----ox*xx---------------------图中的*点从标为(4,4),(打*的位置是空位),则:gStyle(2,4,4,1,1)=1在(4,4)点相邻的上方白棋数为1gStyle(2,4,4,1,2)=2在(4,4)点的上方距上方白棋最近的空格数为2gStyle(1,4,4,3,1)=2在(4,4)点相邻的右方黑棋数为2gStyle(1,4,4,3,2)=1在(4,4)点的右方距右方黑棋最近的空格数为3...一旦把所有空点的棋型值填完,我们很容易地得出黑棋水平方向上点(4,4)的价值,由一个冲1(我把有界的棋称为冲)和活2(两边无界的棋称为活)组成的。
对于而白棋在垂直方向上点(4,4)的价值是一个活1,而在/方向也是活1所以,只要我们把该点的对于黑棋和白棋的价值算出来,然后我们就取棋盘上各个空点的这两个值的和的最大一点作为下棋的点。
然而,对各种棋型应该取什么值呢?我们可以先作如下假设:Fn 表示先手n个棋子的活棋型,如:F4表示先手活四Fn'表示先手n个棋子的冲棋型,如:F4'表示先手冲四Ln 表示后手n个棋子的活棋型,如:L3表示后手活三Ln'表示后手n个棋子的冲棋型,如:L3'表示后手冲三...根据在一行中的棋型分析,得到如下关系:L1'<=F1'<L2'<=F2'<=L1<F1<L2<F2<L3'<=F3'<L4'<F4'=F4从这个关系包含了进攻和防守的关系(当然,这个关系是由我定的,你可以自己定义这些关系)。
对这些关系再进一步细化,如在一个可下棋的点,其四个方向上都有活三,也比不上一个冲四,所以我们可以又得到4*F3<L4'这个关系,同样,我们还可以得到其它的关系,如:4*F2<L3、4*L3<F3...,这些的关系由于你的定法和我的定法制可能不一样,这样计算机的AI也就不一样,最后我们把分值最小的L1 '值定为1,则我们就得到了下面各种棋型的分值,由C语言表示为:F[2][5]={{0,2,5,50,16000},{0,10,30,750,16000}};L[2][5]={{0,1,5,50,3750},{0,10,30,150,4000}};F数组表示先手,第一个下标为0时表示冲型,第二个下标表示棋子数,则F2'对应F[0][2]L数组表示后手,第一个下标为0时表示冲型,第二个下标表示棋子数,则L2对应F[1][2]Ok,棋型的分值关系确定好了以后,我们把每一个可下点的四个方向的棋型值相加(包括先手和后手的分值),最后选择一个最大值,并把这一点作为计算机要下的点就OK了:)。
后话:1、得到最大值也许不止一个点,但在我的程序中只选择第一个最大点,当然你可以用于个随机数来决定选择那一个最大值点,也可以对这些最大值点再作进一步的分析。
2、在这个算法中我只考虑了周围有棋子的点,而其它点我没有考虑。
3、可以再更进一步,用这个算法来预测以后的几步棋,再选择预测值最好的一步,这样电脑的AI就更高了4、这个算法没有考虑黑棋的禁手(双3、双四和多于五子的连棋)。
因为在平时我下的五子棋是没有这些禁手的。
“人工智能”即指让机器具有类似人类一样的主观能动性根据当前情况做出相应的判断,而他的核心便是具体的数学算法。
然而这个算法其实就是依托在一个人造的数学模型上。
具体简单的说,就像本文介绍的五子棋,我们根据五子棋的具体规则建立适当的数学模型,只要机器按照此模型进行逻辑判断就可以得出一定的结果,而这个结果在我们人类看来就是机器在下棋的过程中攻守兼备,仿佛具有人类的智慧。
说到这里,我们就这话题再探讨一点。
“人工智能”的终极目标就是使机器具备人类的情感,而这个目标有可能实现吗?鄙人的看法是绝对可以的,只是时间的问题。
计算机科学从来不是一门独立的学科,他是人类文明的一个结晶。
众学科的综合造就了他,而他也必将超越我们人类。
从生物学角度来看,我们人脑就是有机化合体组成的神经网络;从化学角度来看,我们人脑的化学反应产生的神经脉冲为我们的逻辑运算提供动力;而从数学角度上看,我们人脑神经所以组成的网络正是一个复杂包罗万像的数学模型。
正是在这样一个宇宙的式的数学模型上的逻辑推理,使人类具备了情感。
然而我们人类目前对自身大脑的工作原理认识还处在超低级的阶段,有朝一日人类能更深入的了解我们自身那根据这些知识再将其运用在计算机学科,机器也一定能实现真正的“人工智能”。
有了上面的介绍,我想大家一定对本文所讨论的深度有了了解。
没错,我们接下来讨论的的确是最初级的智能算法。
那么大家在阅读的过程中应该注意的不是这个算法的具体实现,而是根据五子棋规则建立数学模型的这个过程。
即从现实抽象到数学模型的能力,而这个也是编程能力的本质。
规则:分黑白两方,轮流下棋。
率先将5子连线的一方获胜。
目标:使机器在下棋的过程中攻守兼备,就像和一个真正的人类下棋一样分析:为了方便说明我们以5X5 这个最简单的棋盘来加以说明。
棋盘如图所示:接下来我们就五子棋的具体规则特点和人类思维过程讨论一下。
率先将5子连线的一方获胜,那么我们人类在下棋的过程中每下一步前都会思考一下如果我们这样走了后面会出现一个什么样的情况?走了这步后对方会走哪步?如果对方做了这步后会是个什么样的局面,我可以采取哪些走法?......如此这般,从上面我们可以看到我们人类在下棋过程中经历了预见,推理,预见,推理......这样一个反复的过程,然而我们人脑能力有限,我们能预见的步数和记住每步的情况的能力有限制,即使再聪明的人也是有个限度的。
而机器在记忆这方面却是绝对的,所以我们可以模拟人下棋的过程使机器具备高超的下棋能力。
说到这里,也许有朋友会提出:看样子你这就是个深度搜索算法啊。
理论上来说深度搜索算法可以解决任何一个问题,可是事实是有的问题在理论上有解而在现实中却是无解,无法证明的。
比如牛顿三大定律之一:力是改变物体运动状态的原因。
直白的说比如在真空中一个物体背向地球匀速离去,只要没有力作用在它上面它将永远这样运动下去远离地球。