微信斗地主残局闯关8太原关怎么破

利用Python破解斗地主残局详解
转载 & & 作者:Tim
斗地主应该对大家来说都不陌生,下面这篇文章主要跟大家分享了关于利用Python破解斗地主残局的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
相信大家都玩过斗地主,规则就不再介绍了。
直接上一张朋友圈看到的残局图:
这道题我刚看到时,曾尝试用手工来破解,每次都以为找到了农民的必胜策略时,最后都发现其实农民跑不掉。由于手工破解无法穷尽所有可能性,所以这道题究竟农民有没有妙手跑掉呢,只能通过代码来帮助我们运算了。
本文将简要讲述怎么通过代码来求解此类问题,在最后会公布残局的最后结果,并开源代码以供大家吐槽。
代码的核心思想是minimax。minimax可以拆解为两部分,mini和max,分别是最小和最大的意思。
直观的理解是什么呢?就有点像A、B两个人下棋。A现在可以在N个点走棋,假设A在某个点走棋了,使得A的这一步的盘面评估分数最高;但是轮到B下的时候,就一定会朝着让A最不利的方向走,使得A的下一步必然按照B设定的轨迹来,而没法达到A在第一步时估算到这一步的最高盘面评分。
在牌局中是一样的,如果农民的一手牌,让地主无论如何应对都不能赢的话,那么可以说农民有必胜策略;否则,农民必输。
我们可以用一个函数hand_out来模拟一个人的出牌过程。在现实生活中,一个人想要出牌的话,必然需要知道自己手上的所有牌:me_pokers,也需要知道上一手的出的牌:last_hand。如果我们要用这个函数来模拟两个人的出牌,则还需要知道对手当前的所有牌:enemy_pokers。
这个函数的返回值,是轮到我me_pokers出牌时,是否能够必赢牌。如果能赢则返回真,否则返回假。
def hand_out(me_pokers, enemy_pokers, last_hand)
假设轮到我出牌时,如果我手上的牌都出完了,那么我将立刻知道我赢了;反之如果对手的牌都出完了,而我没有,则我失败了。
if not me_pokers:
return True
if not enemy_pokers:
return False
因为现在轮到我出牌,所以我首先需要知道我现在能出的所有手牌组合。注意:这个组合中,包括过牌(即不出牌)的策略。
all_hands = get_all_hands(me_pokers)
现在我们要对所有可能的手牌组合进行遍历。
首先我需要知道,上一手对方出的牌是什么。
如果对方上一手选择过牌,或者没有上一手牌,那么我这一轮必须不能过牌,但是我可以出任意的牌
如果对手上一手出了牌,则我必须要出一个比它更大的牌或者选择这一轮直接过牌(不出牌)
关键点来了,在出完我的牌或选择过牌后,我们需要用一个递归调用来模拟对手下一步的行为。如果对手的下一次出牌不能获胜的话,则我这一次的出牌必胜;否则,对于我的每一个出牌选择,对手都能获胜的话,则我必败。
全部代码如下:
def hand_out(me_pokers, enemy_pokers, last_hand, cache):
if not me_pokers:
# 我全部过牌,直接获胜
return True
if not enemy_pokers:
# 对手全部过牌,我失败
return False
# 获取我当前可以出的所有手牌组合,包括过牌
all_hands = get_all_hands(me_pokers)
# 遍历我的所有出牌组合,进行模拟出牌
for hand in all_hands:
# 如果上一轮对手出了牌,则这一轮我必须要出比对手更大的牌 或者 对手上一轮选择过牌,那么我只需出任意牌,但是不能过牌
if (last_hand and can_comb2_beat_comb1(last_hand, hand)) or (not last_hand and hand['type'] != COMB_TYPE.PASS):
# 模拟对手出牌,如果对手不能取胜,则我必胜
if not hand_out(enemy_pokers, make_hand(me_pokers, hand), hand, cache):
return True
# 如果上一轮对手出了牌,但我这一轮选择过牌
elif last_hand and hand['type'] == COMB_TYPE.PASS:
# 模拟对手出牌,如果对手不能取胜,则我必胜
if not hand_out(enemy_pokers, me_pokers, None, cache):
return True
# 如果之前的所有出牌组合均不能必胜,则我必败
return False
以上核心逻辑理清楚后,构建破解器将变得十分简单。
首先,我们要用数字来表示牌的大小,这里我们用3表示3,11来表示J,12表示Q,依次类推……
其次,我们需要求出一个手牌的所有出牌组合,这里需要get_all_hands函数,具体实现比较繁琐但是很简单,就不在此赘述。
然后,我们还需要一个牌力判断函数can_comb2_beat_comb1(comb1, comb2) ,这个函数用于比较两组手牌的牌力,看是否comb2可以击败comb1。唯一需要注意的一点,在斗地主的规则中,除了炸弹外,其他所有牌力均等,只有牌型一样时才能去比较。
最后,我们需要一个模拟出牌函数make_hand(pokers, hand) ,用于求出在手牌为pokers的情况下打出一手牌hand后,剩下的手牌,实现也非常简单,只需简单的移除掉那些打出的牌即可。
由于一副牌的可能手牌巨大,导致递归的分支数巨大。所以时间开销非常大,为阶乘级O(N!),根据,大约为O(N^N)。
由于可能会有很多重复的牌面出现,导致了很多重复的递归调用。所以加一个缓存能极大提升效率。
即对我方手牌和敌方手牌和上一轮手牌的描述(str(me_pokers)+str(enemy_pokers)+str(last_hand))为键,将求出的结果存进缓存字典中。下一次遇到相同的局面时,即可直接从缓存字典中取出,而无需再次重复计算。时间复杂度优化为指数级O(C^N)。
代码运算出来的结果是,农民没有必胜策略。换言之,只要地主会玩,农民不可能赢。阶级固化已经如斯了么……
代码放于Github: ,或者大家可以,MIT协议,随便玩。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具微信上的斗地主残局怎么解?附图_百度知道
微信上的斗地主残局怎么解?附图
欢乐斗地主残局19关怎么破解
我有更好的答案
地主然后出5,你出7,地主出Q,你出K,,然后地主出4,你出9你先出对4,地主对8,然后你不要
采纳率:46%
来自团队:
为您推荐:
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。有微信上有有一个斗地主的残局若破的牌怎么才能赢_百度知道
有微信上有有一个斗地主的残局若破的牌怎么才能赢
我有更好的答案
先出3到J的顺子,四个二带7和K,对A,A地主先出K,上家大王,下家8到Q的顺子,下家7,地主出A,上家顺子,地主炸,7到J的顺子,3到7顺子,对3。这局关键是炸弹要炸上家的顺子不能炸大王。如果不需要打出炸弹就很简单了
采纳率:85%
来自团队:
为您推荐:
其他类似问题
斗地主的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。斗地主残局。求高手破解。【太原吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:1,122,941贴子:
斗地主残局。求高手破解。收藏
刚才看到的斗地主的残局,求解!!!!!!! 地主:大王,小王,JJ,999 农民:AAAA,对10,单7、6、5、4,3333 另一个农民:已经没有战斗力了,所以忽略,不予考虑 规则:双方都是明牌,农民先出,不准3带2,其余规则和QQ上一样。3带1.顺子都允许的。 结果。农民先出,要农民赢
大皇帝页游新区入口,三国SLG战争页游,点击领取礼包,新服送首冲高返利!
出啥哇不是一王炸呼死了?
只可以三带一
先出一个尖
34567 一王炸下来 完了他要么走999,J 要么单走J 咋你也能封死了哇
对方如果不要,再出34567,然后333带10,111带10
这么简单,还求解,楼主劝你不要玩斗地主了
结论:地主必胜!但过程不简单。。。农民想赢只能靠地主误算!如下:首先农民第一手只能出A!(其他出法速败不解释!)一、地主如不要——农民34567——地主还是不能要(地主如大小王炸则必败)——然后农民出333+10(剩AAA+10)——地主首先不能顺,炸则剩999JJ,必败!二、地主只能打农民的第一手A(哪个王都行)——然后农民不要,让地主出!(农民如3333炸,则速败不解释!只能让地主出。)农民此时剩AAA对,地主此时剩JJ999和一张王。地主理论上有8种出法:1、一张J2、一对J3、999+J4、999+王5、9996、一张97、一对98、一张王逐个分析:8、一张王——属脑残打法,必败不解释。7、一对9——农民出一对10——地主如不要,农民,AAA,地主无解!——地主如用JJ打,农民对A,地主打不住!——然后农民+A,地主无解!6、一张9——农民出一张A——地主如不要,农民,AAA,地主无解!——地主只能用王打!——农民不要!!!——此时农民剩AA,地主剩JJ99——地主不管出哪一对,农民对A打住,然后,10,地主无解!——地主如出单张,则不管出J还是9,农民都用A打住,然后+A,对10,地主无解!5、999——农民AAA打住,然后,10,地主速败无解!4、999+王——农民AAA+10打住,然后,地主更速败无解!3、999+J——同上一条,脑残打法!2、一对J——农民对A打住!——此时地主剩999+王——农民34567——对10!!——333+A!地主无解!以上是农民能赢的方法!1、一张J——地主唯一能赢的方法!(一)如农民不要,地主再出一张J!!!(注意此时不可出999+J或者直接出王,否则必败!比较简单不解释。)此时地主剩一张王999,农民则必须用A打(不能3333炸!否则无论如何过不去地主的王,速败!),然后地主王打!农民则必须3333炸掉了!——此时地主剩999,农民剩AA——注意农民有4567四张小牌,无论怎么出,地主都可以把三张9顺出去,胜利!(二)农民如用A打,地主用王打!——地主剩999J了,农民则必须3333炸!——此时农民依然剩AA,只能出小单张(以4为例)——地主顺一张9!(1)、农民如进10,则地主进J,农民A打住后,还有567三张小单,无法对抗地主的99!地主胜利!(2)、农民如直接A打住,则只能继续出小单张(以5为例)——地主再顺一张9!——农民如顺10,地主顺J,农民A,此时农民还剩67两张小单,无法对抗地主的单9!——农民如继续A打住,则剩671010,依然无法对抗地主的9J!地主胜利!!以上为我的详细分析,有不同意见的朋友请批评指正!总结:类似街头象棋残局,地主逗你玩!。。。
看了9楼才知道楼主是骗回复的。。这是网上的段子哇?
都是明牌 你看清没
不对 农民咋也赢不了哇我觉得
貌似无解啊
登录百度帐号推荐应用微信上的斗地主残局怎么解?附图_百度知道
微信上的斗地主残局怎么解?附图
我有更好的答案
先出2222k7,再J,再AA,33。获胜
采纳率:100%
的画面不在
简单,长顺4到K再对A最后怎样出都可以了
有什么要求吗
地主赢不了
没理由,长顺他们吃不起,对A他们也吃不起,剩下3带1和炸2,怎样出都会赢的呀
看错了少了个Q
那就必须拆2,长顺4一j,三个3带7回头三个2带K,最后再出单2
右上角的顺子可以压我的,还是不行
是不是有吃必须得吃的,如果是那就可以先出3到7的顺子,
可以四带2的吗
可以就3到j顺子,对A再4个2带7和K,最后对3
不对,先出单k,它拆A就炸2然后3到J,再对3,对A收回,最后单7
拆2啊。。j,三个三带七,三个二带k,然后对A。
怎么不行?
三带一,顺子,二炸,对子,单
三带七,二带K,一对烟,顺子!
还是不行,咋回事
怎么不行?
哪里卡了?
要不你直接打出组合给我,再试试
三个3带7,然后三个2带K压
相信我。出完顺子(还剩一个2),右上角立马会出一个顺子,还是赢不了~
我还能剩一张牌,厉害吧
这已经还牛逼了
34567,让下家打,k大,然后下家打Q,地主打K,上家王,等上家打掉顺子就炸,下来随便打
本回答被提问者采纳
4.5.6.7.8.9.10.11顺子先走然后3个3带一个炸弹扔出去对A单张出完胜利
手上试不到,不知道电脑怎么出的你先把不能留的扔出去先扔个7试试,然后K看看能不能扔出去,最后要是你用了一张2电脑要是用大王你就让他出无论是出什么用2那会出牌权3到11对A最后把对三出掉
本回答被网友采纳
2条折叠回答
其他4条回答
为您推荐:
其他类似问题
微信 斗地主残局的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 微信斗地主残局闯关8 的文章

 

随机推荐