真人扑克游戏
点击注册
点击注册
.

如何写一个斗地主的AI?

发布日期:2024-03-27 15:10    点击次数:94

  提前声明一下,我只是一个编程新手,水平不高。

毕竟是一年前的问题了,也许我现在的水平已经远远比不上题主。

  首先我们需要明确斗地主这种牌类游戏与其他AI的区别,如棋类游戏,以选取针对性的算法。

棋类游戏的局面对玩家是公开的。

因此我们可以用基于决策树的算法,如alpha-beta剪枝对之后的很多步进行模拟,找到最优解。

而斗地主这种牌类游戏,由于我们得到的信息相当有限(只有自己的手牌与对手打出的牌),很难搜索很多步,基本还是靠“专家系统”-以人类思维进行模拟,将人类智慧中的一些术语转换为计算机能听懂的语言。

  前不久刚刚写了一个斗地主AI。

我认为关键在于拆牌和估值。

我们认为“牌”是0-53的数字序号。

其实也可以无视花色,将其视为0-14(0代表3,14代表大王)的数字序号,允许重复。

  先实现数据结构。

需要定义一个类:牌组(不妨叫CardCombo),给出一堆牌的输入,这个类需要确定牌组的类型(如对子,三条,飞机,顺子等等),大小(如对6>对4)。

判定牌组类型考虑牌组中同点数牌的数量。

比如牌组中同点数牌数量为1(3-大王,任何点数仅有1张),可能是单张或者顺子。

同点数牌数量2-对子,双顺。

3-三条,飞机。

3+1-三带1,飞机+小翼。

这需要自己慢慢分类讨论。

  接下来是出牌。

斗地主出牌有两种:一种己方是先手,无限制的出牌(认为是攻击型的),另一种是跟牌(认为是防守型的)。

出牌的合法输出仅取决于自己手牌(出自己有的牌),而跟牌需要:出自己有的牌,牌类型与所跟牌:类型相同,张数相同,等级较高。

实现了这一点之后,您可以设计出有牌就跟的AI,合法性是可以保证的,但是这样的AI战斗力不高。

  想提升AI战斗力,您或许需要实现拆牌的功能,即将手牌拆分成比较好的组合。

这里的“好”,粗略指的是手数尽可能少,但尽量用对牌组的估值进行判断。

澳门一烂赌菲佣疑趁雇主外游,偷取名表及现金用作赌博。

澳门城区发展促进会理事长陈德胜形容,澳门的非法卖淫活动“日日都有”,“一楼多凤”匿藏于大厦内,不但影响住户及小区的卫生安全,更担心不良风气祸延下一代,希望政府严厉打击卖淫活动。

比如手牌是33345677,我认为常人思路应该是拆成(34567)(33)(7)。

这里提供一个简单思路(我的思路加入了大量特判,之后举例优化。

)拆牌顺序:炸弹-三条-双顺-顺子-对子-单张。

例如0JQQK。

拆分结果应如(333)(445566)(7)(888)(910JQK)。

这比有牌就跟的AI相比就要好很多。

优化很多,比如发现破坏对子数量过多不拆顺子,将双顺拆成两个顺子(3445566778拆成34567与45678)等。

  对于一个可以当做一手牌打出的CardCombo,我们可以对它进行估值。

整手牌的估值就是这些拆分好的牌组与牌组数量(出完牌需要的轮数,越小越好)的线性组合。

这里粗略说一下估值的思路,大牌肯定要设计成高权值。

特殊类型的牌权值也应该有增益。

如33一般是优于单张3的。

  接下来是进攻性的主动出牌了。

一般自己有好的牌型(如双顺,飞机,顺子)对手难以管上,可以优先出,占据主动权。

更强的AI要考虑队友与对手可能没有的牌型,针对弱点进行进攻,或避免卡队友。

  防守型的被动出牌其实不一定要出拆好的Combo中的牌,因为给了跟牌的限制,搜索数量并不多。

这里可以假设出某个Combo,估计剩下手牌的价值,如果破坏牌组并不严重,就可以出这个Combo.

  再优化就是残局搜索了。

比如,自己剩下两手牌,有一手是绝对大牌。

比如双王已经出过,你手里一张2一张7,先出2先出7?答案是先出2.这种局面想优化需要好好考虑。

  这个框架是基于人类经验的。

其实需要考虑的事情很多,再提升性能也很困难。

现在BP神经网络比较流行,思路是将(我方有的手牌,上家出的牌,已经出过的牌)作为完全描述已知信息的游戏状态state,作为神经网络的输入,计算出我方选择所有合法动作(action,也就是可行的操作-出符合游戏规则的牌或跳过)的概率。

但是凭我目前的水平很难实现。

也许之后实现神经网络会更新答案。



栏目分类
棋牌游戏资讯