斗地主策略说明

发个策略介绍,大伙来写个斗地主的AI来PK?

------------------------------------------------

以斗地主策略说明(不仅涉及博弈论,还涉及概率、逻辑推理和心理学):


1. 什么情况下应该要地主?


一副牌总共有四个2,两个王,我们叫大牌。


可能出现的情况有:

1)无大牌。这个时候明显不能要。

2)有1张大牌。如果是2,不要。如果是大王,牌型整齐两手出完可以要。总体建议不要。

3)有2张大牌。两个2,不要。一2一小王,建议不要。一2一大王,牌型整齐可要。

4)有3张大牌。一个2两个王,两个2一个小王,两个2一个大王,三个2。总体可要。

5)有4张大牌。两个2两个王,三个2一小王,三个2一大王。总体可要。

6)有5张大牌。三个2两个王,四个2一小王,四个2一大王。要。

7)有6张大牌。四个2两个王。要。


一副好牌是什么意思?平常,我们看到大牌就高兴,包括王、2、A、K多这样的牌。牌力大,这是牌好的第一层意思。


牌好的第二层意思,需要考虑牌的整体结构,即牌的整齐度。这在实际情况中是被很多人忽视的。有的人经常拿双王两个2没有打赢,往往因为其余的牌太散,也就是牌的整齐度不好。


综上,拿到牌要不要地主有两个维度的考虑:一是牌力大不大,二是牌的整齐度好不好。


不要赌底牌,底牌出现想要牌的概率很小,小于10%。


2. 地主出牌方法:


1)拿上牌后,分析自己的牌,除开三带一后,剩下的单牌在10点及以下,则发单。如果自己大对子比较多,能收回对子,便发对。如有几个三带一就先发三带一。


2)地主要尽量不要把自己的弱点暴露在对手的面前,也就是如果没有大的对子,首发就尽量不要打对子。人家打对10左右你就不要了,那弱点一下就给暴露了。 


3)地主要学会忍让,如果不管是哪家的牌你都要打死,那么你的牌再大也是要输的,如自己发单,别人打大单,但自己有大对子那么就没有必要拆开2去打,因为对方肯定有对子投起来的。 


4)地主要算准下家的单牌过到几、对子过到几。(通过发单时算、还可通过三带所带的牌来算)。 


5) 地主走一张单,地主下家直接就走一个2,要直接打掉。


3. 地主上家出牌方法: 


1)地主发单,顶大单,上手则改打中对;地主发对子,同伴出小对子则卡住地主的小对子,卡住对8以下的,可出对7、8,让同伴接过去;若同伴出到对10左右则千万不能接同伴的牌,在同伴打不起时在接打地主,上手后出大单。


2)同伴上手后,发小单过来,则要顶大单,如果大牌是对子就应该拆开对子来顶地主,上手后继续发中对,但如果前面已经知道同伴没有大对子了,则可以在顶牌时稍微顶小点,顶到10左右,让同伴去接地主的单牌。 


3)看着牌很可能打不赢的时候,可以采用特殊的方法。如有一个A、2、加上几张烂牌,顶牌A,地主不要,这个时候就打一个2,这样如果地主不是双王,他必然会用王打你,这样就让地主少过了一张牌,给同伴创造了更好的机会,如果地主是双王,他牌不好他也可能把双王给拆掉,(本来他可以炸出来的)这样,就被你给骗到了,这种情况能逼地主不炸就为赢了。


4)地主上家要算好地主是单牌差劲还是对子差劲,专门打地主的弱点。如果地主单牌过完了,便发单,分死他。


5)地主上家一定要记住自己的任务:顶牌,卡主地主的单牌和小对,让他出不了


6)如果牌很好,可不顶牌。但至少要有80%以上把握才能这样放。 


4. 地主下家出牌方法:


1)地主发单,过小单;地主发对,过小对;地主出大单,选择性的拆2。 


2)接打同伴的中大单和对子,上手后有单牌一定要出单,单牌很大也可出对子,无单了出对子。


3)报单双时,如果地主过的单牌很少(地主上家顶住了牌没有让地主过小单),就报大单,否则报双。 


5. 算牌


1)算炸弹 

例:自己无2,出A见小王,则极可能有2222。


2)算大牌

例1:自己地主大+22先手出A下家出小,则必有一家22成对。 

例2:自己地主大+2先手出单下家出2,则极可能上家有22。


3)记牌

任何人都必须记住的:王,2,自己的缺牌,10,7。


6. 合作


1)单不放10,双要过6。

上家顶地主,尽量单牌不要小于10。对子出到66最好,一来不让地主放小对,二来可以知道关于7的重要信息。


2)不压队友。

队友牌好让队友出,不可逞一时意气。


3)地主剩一张时。 

若能不放单就走掉,固然最好,若不能走则要求密切配合了。最基本的路数是,若上家走则走,若不能走则以最大的牌依次顶地主,然后放对让下家接;下家接上后,若能走则走,若不能走,则放单;上家再重复刚才的路数。


4)地主剩两张时。 

任何情况下,除非已算出地主所剩为两张单牌,否则不要出对。一直出单,直到地主出一张为止,若地主始终不出,那就一直出单,把对子全部拆成单张出,地主出一张后,再照上面的打法进行。


三方信息开始时是比较对称的,每个人都只知道自己的牌。但是游戏进行过程中,高手可以通过自己的缺牌、已出牌、上下家打法,据此推理分析得知一般人不知道的重要信息,由此制定优势策略,增加获胜几率。


最后,三个人坐的位次很重要,千万不要让个猪一样的队友坐地主上家。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
斗地主算法策略可以分为两部分,一部分是出牌策略,另一部分是叫牌策略。 出牌策略: 1. 单牌:优先出手中最小的单牌。 2. 对子:优先出手中最小的对子。 3. 三带一:如果手牌中有三张相同的牌,优先出三带一,且出的牌要尽量小。 4. 顺子:优先出最小顺子,如果有多个顺子,则出最小的那个。 5. 连对:优先出最小连对,如果有多个连对,则出最小的那个。 6. 三带二:如果手牌中有三张相同的牌,并且有一对,优先出三带二,且出的牌要尽量小。 7. 炸弹:如果手牌中有炸弹,优先出炸弹。 8. 飞机:优先出最小的飞机,如果有多个飞机,则出最小的那个。 叫牌策略: 1. 地主牌:如果手牌中有地主牌,优先叫地主。 2. 炸弹:如果手牌中有炸弹,优先叫炸弹。 3. 双王:如果手牌中有双王(大王和小王),优先叫双王。 4. 对子:如果手牌中有对子,优先叫对子。 5. 单牌:如果手牌中有单牌,优先叫单牌。 下面是一个简单的 Python 代码示例实现: ```python import random # 手牌 hand_cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] # 地主牌 landlord_cards = [33, 34, 35] # 出牌策略 def play(hand_cards, played_cards): if not played_cards: # 第一手出牌,随机出一张牌 return random.choice(hand_cards) else: # 根据出牌策略出牌 if len(played_cards) == 1: # 出单牌 for card in sorted(hand_cards): if card > played_cards[0]: return card elif len(played_cards) == 2 and played_cards[0] == played_cards[1]: # 出对子 for card in sorted(hand_cards): if card > played_cards[0] and hand_cards.count(card) >= 2: return [card, card] elif len(played_cards) == 3 and played_cards[0] == played_cards[1] == played_cards[2]: # 出三带一 for card in sorted(hand_cards): if card > played_cards[0] and hand_cards.count(card) >= 1: return [card, card, card, hand_cards[0]] elif len(played_cards) >= 5 and len(played_cards) % 2 == 0: # 出连对 for i in range(2, 15): combo = [x for x in range(i, i+len(played_cards)//2)] if set(combo).issubset(hand_cards) and combo[-1] > played_cards[-1]: return combo + [hand_cards[0] for i in range(len(combo)//2)] elif len(played_cards) >= 6 and len(played_cards) % 3 == 0: # 出飞机 for i in range(2, 15): combo = [x for x in range(i, i+len(played_cards)//3)] if set(combo).issubset(hand_cards) and combo[-1] > played_cards[-1]: cards = [] for card in combo: cards += [card, card, card] cards += [hand_cards[0] for i in range(len(combo))] return cards elif len(played_cards) == 4: # 出三带二或炸弹 for card in sorted(hand_cards): if card > played_cards[0] and hand_cards.count(card) >= 3: return [card, card, card, hand_cards[0], hand_cards[0]] for card in sorted(hand_cards): if card > played_cards[0] and hand_cards.count(card) == 4: return [card, card, card, card] elif len(played_cards) == 2 and played_cards[0] != played_cards[1]: # 出单牌 for card in sorted(hand_cards): if card > played_cards[0]: return card elif len(played_cards) == 4 and played_cards[0] == played_cards[1] == played_cards[2] == played_cards[3]: # 出炸弹 for card in sorted(hand_cards): if card > played_cards[0] and hand_cards.count(card) == 4: return [card, card, card, card] else: # 只有炸弹可以大过 for card in sorted(hand_cards): if hand_cards.count(card) == 4 and (not played_cards or card > played_cards[0]): return [card, card, card, card] # 无法出牌 return [] # 叫牌策略 def call_landlord(hand_cards): # 根据叫牌策略叫牌 if 33 in hand_cards and 34 in hand_cards: # 叫双王 return 1 elif len([card for card in hand_cards if card > 10]) >= 5: # 叫炸弹 return 1 elif len([card for card in hand_cards if hand_cards.count(card) >= 2]) >= 1: # 叫对子 return 1 elif len([card for card in hand_cards if hand_cards.count(card) == 1]) >= 3: # 叫单牌 return 1 else: return 0 # 测试代码 print("手牌:", hand_cards) print("地主牌:", landlord_cards) print("叫牌:", call_landlord(hand_cards)) print("出牌:", play(hand_cards, [])) print("出牌:", play(hand_cards, [3, 3, 3])) print("出牌:", play(hand_cards, [3, 3, 3, 4, 4, 4])) print("出牌:", play(hand_cards, [3, 3, 3, 4, 4, 4, 5, 5])) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值