斗地主机器人智能算法深度研究

        我从事棋牌开发工作已经6年了,我一直喜欢玩斗地主,腾讯上面的我经常玩,别人的也经常玩,对于斗地主机器人智能效果,一直都未发现那个平台做得比较令我满意,所谓的好,我觉得机器人常见牌要打得有点水准,拆牌,顶牌必须要有,还要比较接近人的出牌逻辑,这样玩家的体验感会好很多,我内心其实一直都有一个好的想法去实现更加智能斗地主机器人,趁着最近工作也比较空闲,为此对斗地主机器人算法进行深度研究,算是略有成效,效果当然远比现在公司的斗地主机器人要好。

    第一步:

          如何判断一手牌的好坏,那就必须要对牌型进行计算分数这样你才能计算出来,这是一个基础定义。牌型的总数有如下这么多种

如果每种的牌型得分如下:const int CARD_TYPE_SCORE[CT_TYPE_COUNT] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 100, 110, 140, 150 };

牌型里面牌有大小之分,这样其实还可以针对牌值进行加分,这样牌的分数就比较细腻,牌值的分数就是加上他的牌的逻辑值就可以了

,还有一点要注意,牌的手数少的话,也应该适当加分,何为手数?就是以最快的出牌方法,手上的牌可以多少次出完,一般情况下手牌数少,牌应该要适当加分,加分策略如下:

第二步:

       斗地主有叫分过程,这个也是有讲究,我的定义是这样

可分数低于370分时,不会进行第二次叫分,这个也是保守叫分法,如下

第三步:

      出牌总共分为6个大的策略分支:

比较重要的出牌策略,是地主压牌和地主上家出牌,和地主上家压牌策略,

先说地主压牌策略:

上面是所有出牌的基本策略就是只剩下火箭带一手牌,或者炸弹带一手牌,或者是最后一手牌,那是必须要出的,这是6种出牌策略里面都要有的,下面是细分

地主下家出牌时,如果最快的速度出牌策略(CommonTypeTrunCard里面是不包含火箭压牌,火箭压牌必须是特别处理的)里面没有牌能压下家牌时,可下家手牌只有一张了,那么这时必须启动搜索牌面最大炸弹(手上的炸弹是否是最大炸弹),或者是火箭去拦截,

当上面的小策略失效时,那么必须启动拆牌策略(一般只有在单牌,双牌时才会拆牌):

上面的策略都失效了,那么后面还有一条非常体现智能效果的策略,就是前面的策略都失效了,那么要尝试一下最后一条策略

那就是其他两家有人只剩下两个牌时,一般这时地主要考虑拆牌了,

vecMinTypeCardResult这个结果里面包含的是最快出牌的牌型数据,CardTypeResult这个结果里面包含的是所有可组成的牌型数据,前者是提供常用策略来使用的,后者是借硬性策略使用的。常见策略失效了,那么就不能那么死板按照最快出牌策略那样按兵不动了。这个举个例子你就明白了,地主手上有2,AAA,99,88,66,5,有人出了一对KK,他手上剩下10张牌,这时按照最快出牌策略的话,是不应该拆AAA去打的,因为出牌者手上还有可能有其他牌型,可以守株待兔,可要是出牌者手上牌只剩下2张以后了,那么AAA就必须拆了。

地主上家出牌相当重要,优先出不是单牌的牌。(当然有人会说出自己能收得回来的牌不更加好吗?这个就是更加高一级的策略了,更加精细的做法了,这个可以留到以后来优化)

地主上家压牌,就要看是压队友的牌还是地主的牌,地主的牌一般是能压都会压,队友牌一般情况下小于K跟牌就行了,大于k不要跟了

当然大策略就是基本上是上面这些了,小策略就不再去详细说了,,详细说1万字都说不完。

这些是根据我自己的打牌经验的策略来写的,当然斗地主高手还会有更加好的策略可以加进去,这样效果会更加好。

上面这个FindCardKindMinNum搜索算法也相当关键,才是核心,如果要从20张牌里面所有的组合算出来,然后进行牌型分比较,进行筛选出牌最快,牌型的最好的牌,那么最复杂的情况有5000万种组合,现在普通的计算机是顶不住的,就算是1000万种组合的我在

这个处理器下跑出来也要40多秒,所以我对很多牌型进行了剪枝,这样一般最差的情况是30秒就算出来了,效果算是打了个折扣吧,但也不至于出牌效果很差,这个真正要运营的话,得用阿里云计算型的服务器来跑,这样效果会好很多。

现在我的剪枝过后的算法,一般情况下不会超时,出牌效果如下

如果你的斗地主按照这种牌,能以这样的方式出完,那么效果也是不错的了,

这个是我利用工作空闲时间,研究了20天的效果,过程非常辛苦。

如果有朋友有更加好的想法,欢迎一起留言交流,敬请踢教。Q:460000713

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章