简易五子棋&AI权值法(2)
权值法
权值法实现AI,就是给每个无子的地方给一个权值,然后选出权值最大的让电脑落子。
具体到每个位置,权值根据周围一定范围的落子情况给出。
就我的想法来说,我觉得这个某一个位置的“一定范围”,如果细究的话应该是全盘所有其他位置,也就是说无论距离这个位置的远近,或者有无落子,都会对这个位置产生影响。
比如:
● _ _ _ _ _ _ _ _ _ ★☆
(_代表无子,○代表玩家的执子,●代表电脑的执子,后同)
当要计算★位置的权值的时候,要不要考虑最左边这一颗棋子呢?实际上,★位置和左边这颗棋子一定不可能成五子,但另一方面,你不能否定如果只考虑这三个位置的话,在☆和★两个位置落子对输赢的趋势影响还是略有区别的。(如果是我,我会选择在★落子)。
可你再想想,如果这种局势让你选,你一定选择落在紧挨着●的下一个位置。也就是说,纠结★位置的权值没有意义,我们姑且先这么认为。另外,人脑有限,要考虑到全盘去给某一个位置赋权是不值当也是几乎不可能实现的。
(以上可能只是庸人自扰,勿喷)
接下来,确定这个范围,我按照我见过较多的做法,也就是考虑以这个位置为端点的射线上的四个棋子来赋权值。(就一步而言,至多这四个位置有影响)。四个位置,每个位置可以是●或○或_,也就是说有3^4=81种情况,再思考一下,会发现对于★○xxx这种情况,x无论是什么对★没有影响,类似的还有,★_○xx,★__○x。这样一来,实际上我们需要考虑的只有:(★在每种情况的左边,未画出)
这31种情况,将这31种情况给出不同的权值,然后对每个空位置的8条射线依次辨明是哪一种情况,然后加上该种情况的权值。
一般来说,活4会比活3的权值要大得多,而活5又会比活4大得多。究竟大得多是大多少?说下我的想法:
因为活4就已经是九成可能赢了,为了防止有4个活3撼动一个活4的地位,所以活4比4倍的活3(4倍的理由后面会解释)大;而活5就更不用说了。(虽然上面这种情况较为极端,但我们要尽可能做最坏的打算)。
这里还有一个问题,按照上述来赋权的话正常情况下,●●●_(活4)会比●○xx(眠2),●●●○(眠4)的权值要大得多,但考虑下面两种情况
很明显,如果按照上面对赋权方法,(1)应该是会比(2)要小的,但实际上(1)合理的权值应该是最大的权值(五连)。
所以,单一分别考虑8条射线缺陷其实显而易见。
解决这个问题最好的方法就是考虑8条射线转换为考虑该位置为中心的4条9个位置长度的直线。这也就是上面为什么说最多4个(4倍)的原因,如果有5个及以上活3或活4的话,那必有活5,就没必要再讨论活3了。
至于其他情况,我也都是根据棋艺和感觉以及适当参考上面的思想来设定的。
(可能是我比较蠢)如果直接这么去赋权的话,共有3^8种情况,……就算要剔除不可能的情况也很费事>()<。
所以,就用上面讨论过的31种情况去组合出这4条直线。也就是,做一个31*31的权值矩阵。(呵呵呵呵呵)
实际上,我做了,按照我乱七八糟的棋艺做了。可做完之后有人指点我又发现,
★__●●,★___●……这样的情况,有必要考虑吗,这种情况我们不是优先在连子多的地方下吗?相反,★位置不仅不能给较大的权值(相对于活1,活2……),还要给他一个负的权值,因为这种局面落子就不应该落在★的位置,给它正的权值还会干扰其他位置。
基于种种考虑最后我将情况简化为了20种。
当然,上面只讨论了站在电脑角度去‘攻’,用同样的方法可以实现‘防’(即将玩家的棋子视作电脑的棋子)。不过我将每种情况‘防’的权值只设置成‘攻’的0.8。我方五连的权值一定要是绝对大的,防止敌方2个或3个五连撼动我方5连。
利用权值矩阵实现AI这部分代思路并不是很麻烦,需要注意的是要处理碰墙的情况(一条直线不满9个位置)。此时,我的简单权值AI就实现了,而且它的水品的确还是挺不错的(不枉我20*20的权矩阵,放在最后)。
—————————————————————————
和它下了很多盘后,我发现‘它’还是有很明显的弊病,就是太贪心于现状,也就是说,如果与它对弈时,尽量避免连在一起落子,而是几个方位散落,最后落子让几条线都活3或活4,它就会难以兼顾。简单来说,套路很容易打败它。虽然,这与我所赋权值有关系,但我觉得根本原因是考虑情况太少。也就是到了这个时候,就考虑4个位置而言我又回到初始的心态,考虑所有31种情况,一定是比20种要好的(如果有很好的的权值,这样完全可以实现一些简单的套路);再进一步讲,几乎可以肯定的说,要计算权值的这个位置的权值受其他所有位置落子情况的影响。当然,无论怎么说,你得有一个不错的权值表。权值法,AI的能力几乎完全取决于权值。
————————————————————————
以上仅为个人看法,若有错误或不当,请见谅。
权值表:(1同●,0同○)