快捷搜索:

战神

新葡京

kaifa

博天堂娱乐城

博天堂娱乐城

注册游戏账号

凯发

凯发娱乐城

游戏开户

战神

战神娱乐城

真人游戏开户

斗地主AI设计分享(长篇)

  很可惜,大部分的why我都无法说出逻辑清晰的所以然,于是我只能在鬼蟹的lol平衡性调整文章中看的超级爽,但说不出什么来。

  不过,以斗地主为例的话,就很容易说清楚这个why了,我要做的就是尽可能把AI做的像真人一样,让玩家觉得时刻都能找到“人”陪他玩。

  首先,how对应的对象是机器人、是程序、是死物,对它们而言,是没有“感觉不对”、“感觉慢来”这类的说法,对他们而言只有条件判断if和数值(数字)。以斗地主为例,我们要把平常的出牌经验,全部抽象成为数字,例如我说我的牌好,要转化成分数高;出这手牌好,要转化成为,我(或者我的队友)的分数变高了,或者对手的分数降低了;这手牌能不能出,要转化为,出了之后收益多大,但让对手胜利的概率又有多大;等等。

  (注:由于目标是嵌套到已存在的斗地主程序里面,而程序员希望他要做的事情越少越好,所以这个斗地主是一个不完整版,它缺少记录出牌流程并加以分析的模块,只有对应当前的状态,选择合适的出牌策略的流程。不过测试结果已经比较接近真人的行为了,完整版将会在未来补全。并且牌的数值代号是以他的规则定义的,而不是最合适AI设计的定义,所以需要有一些转换的函数,只是看起来同一张牌有多个数值定义,但对实际功能是没有任何影响的)

  tactics int //确定出牌的策略,1:优势牌全攻,2:中势牌半攻半守,3:劣势牌,全防守

  arrpai [15]int 我们一共15个大小的牌,找15个盒子把他们装起来,盒子最少装0个,最多装4个。

  arr [22][]int //0-7存放顺子,8-15存放连对,16-20存放三顺(三顺一般都进入飞机组了),21放炸弹

  说点题外话,之前我发现,市面上成功项目的系统公开、技术公开还有一些,不过相关的数值体系公开真的少之又少。当时很是气愤,找一些特别想知道的信息怎么就那么难呢?

  然而,做完这个AI设计第一版,测试效果还不错的时候。我突然觉得,整个代码公开是没所谓的(当然,写的太丑,没什么技术成分是关键),但是那些数字,每一个都是我玩几千把斗地主的心血,每改一个数字,都又几十把过去了。不舍得把他们交给别人(是嫁女儿的感觉么?)

  但是,后来想通了,以后会写出更多、更完善、更有价值的数值设计的,现在自己看来的宝石,再未来的自己看来也只是一个路边的石头罢了。抛弃过去,才能早点走向未来。

  并且以手上的牌能否获得收益为价值依据,例如一张A虽然很大可能能打出去,但是不太可能获得上手机会,所以价值是负的,我是大部分时候宁愿少这张牌的。

  (注:这个设置确实差不多了,炸弹吃大王确实是一个数值陷阱,让人觉得炸弹好厉害,但实际效果并不是那么强,高估炸弹很容易有不合理的分数判断)

  但其实,大牌上手并不一定要出小牌,可能会出一些长牌,留小牌最后出。这样小牌的价值就可以忽略了。

  同样的,2+小王 大王,虽然很多时候2+小王也可以上手一次,但是没有大王那样一锤定音。

  但是对A的价值却逆增长,因为对A能称为大牌的时候,远比单张A多很多。而且拆对2很正常,拆对A是不够合理的。未来出牌的时候会有拆牌的需求出现,这时候就要在定分的时候调整了。

  3. 三带1(2)的算分出现不整齐的数字(9),由于是第一版,所以数字都按爱好用5,10表示。

  但是在后期,三带1就称为长牌了,所以要做一个标记,让后期出牌能轻易的找出三带1作为清手牌的时机打出。

  缺陷2:手牌的价值,除了大小以外,还有牌型数的概念,即最少能出几次牌才能打完。例如到你出牌了,你宁愿剩下1张3,而不是一张A加一张2。而我把他们合在一起统计价值了。同上,如果有记录的话,把价值拆分,反而更好的调整两者的价值变化(注:大小价值变化慢,牌型数价值提升快)

  明显不是,我们会有抉择,宁愿小亏都不让对手出牌那么舒服,甚至把自己的牌拆的千仓百孔,自己没办法赢,完全靠队友,也要把对手卡住。这种自损1000杀敌100的行为,是光从分数上无法体现的。这时候,就需要我们一开始就定义的,之前没提到的tactics——出牌策略来决定我们的打法了。

  用那种方式是有牌的分数决定的,分高了靠自己,分低了靠盟友。地主都是全攻类型的,遇到特殊牌型会额外添加处理策略。

  尤其是,我原本做为起始牌组做的策略区分,没有实行动态调整方案,而前期和后期的分界线是不尽相同的。只能作为一个可用的过渡区分吧。

  由于底牌的随机性,这个只要看手上大牌分值经行判断就好了,例如3—10的顺子看起来很爽,摸完底牌就难说了。

  这一个对流程是没有影响的,基本按照score高低经行判断,总的来说加倍要赢是更接近于真实体验,不过挺多人乱加倍的,所以我暂时没作处理。

  // 出牌函数,我大了然后要出牌了,输入牌的slice、上家的手牌数量、下家的手牌数量、庄家的位置(我是0,下家是1,上家是2),输出要出的牌

  唯一复杂的是,由于没有做score的动态调整,所以整个出牌逻辑压力就都集中在这里了。其他两名玩家的手牌数量不同,我们需要做出不同的局面判断。

  (注:具体组合过多,还是代码见吧,核心判断在于对手直接胜利的风险高低,则不一定按最高分值出牌。)

  // 跟牌函数,别人出牌我要出什么,输入牌的slice、上家的手牌数量、下家的手牌数量、庄家的位置(我是0,下家是1,上家是2),底牌的slice,底牌的位置(谁出的),输出要出的牌

  然后一个一个试,基本来说,我是以-95,-155为分界线分,全守就不用管了,烂命一条,破罐子破摔咯~

  但事实上,根据对手直接胜利的风险大小,策略1、2的亏损额度可以一直往上涨,直到不惜代价管上为止。

  3. 策略的排列组合是永远在增加的过程,例如剩4张,剩5张也需要特殊处理的。只是情况并不多而已。

  最好的方式当然是动态调整分数,让分数加上玩家的手牌数参数,但事实上功能是接近的,调整分数是能让策略更简洁漂亮,但是抽象的难度只会增加不会减少。

  4. 亏损的承受能力,比牌型的分数更加没有依据,明显和我的目的,把感觉提炼成数字违背了。但是牌型

  分是通过前面好多场斗地主而提炼出来的,而亏损承受能力,要先有评分标准之后,才能观察出牌情况,才有亏损承受能力数据,简单来说,就是功夫不到位,产出自然不会凭空出现的。

  然而,做完这个AI设计第一版,测试效果还不错的时候。我突然觉得,整个代码公开是没所谓的(当然,写的太丑,没什么技术成分是关键),但是那些数字,每一个都是我玩几千把斗地主的心血,每改一个数字,都又几十把过去了。不舍得把他们交给别人(是嫁女儿的感觉么?)

  但是,后来想通了,以后会写出更多、更完善、更有价值的数值设计的,现在自己看来的宝石,再未来的自己看来也只是一个路边的石头罢了。抛弃过去,才能早点走向未来。

  // 注:这是第一版的,数值效果。可以说是凭感觉随时写出来的,反正当时想着先出来,再慢慢改嘛。

  并且以手上的牌能否获得收益为价值依据,例如一张A虽然很大可能能打出去,但是不太可能获得上手机会,我是大部分时候宁愿少这张牌的。

  (注:这个设置确实差不多了,炸弹吃大王确实是一个数值陷阱,让人觉得炸弹好厉害,但实际效果并不是那么强,高估炸弹很容易有不合理的分数判断)

战神

博天堂

凯发

您可能对下面的游戏相关资讯感兴趣: