视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
一步步解析Python斗牛游戏的概率
2020-11-27 14:35:19 责编:小采
文档

过年回家,都会约上亲朋好友聚聚会,会上经常会打麻将,斗地主,斗牛。在这些游戏中,斗牛是最受欢迎的,因为可以很多人一起玩,而且没有技术含量,都是看运气(专业术语是概率)。
斗牛的玩法是:

  • 1、把牌中的JQK都拿出来
  • 2、每个人发5张牌
  • 3、如果5张牌中任意三张加在一起是10的 倍数,就是有牛。剩下两张牌的和的10的余数就是牛数。
  • 牌的大小:

    4条 > 3条 > 牛十 > 牛九 > …… > 牛一 >没有牛

    而这些牌出现的概率是有多少呢?

    由于只有四十张牌,所以采用了既简单,又有效率的方法枚举来计算。
    计算的结果:

  • 所有牌的组合数:658008
  • 出现四条的组合数:360,概率 :0.05%
  • 出现三条的组合数:25200,概率 :3.83%
  • 出现牛十的组合数:42432,概率 :6.45%
  • 出现牛九或牛八的组合数:87296,概率 :13.27%
  • 出现牛一到牛七的组合数:306112,概率 :46.52%
  • 出现没有牛的组合数:196608,概率 :29.88%
  • 所以有七成的概率是有牛或以上的,所以如果你经常遇到没有牛,说明你的运气非常差或者本来是有牛的,但是你没有找出来。

    Python源代码:

    # encoding=utf-8
    __author__ = 'kevinlu1010@qq.com'
    import os
    import cPickle
    
    from copy import copy
    from collections import Counter
    import itertools
    '''
    计算斗牛游戏的概率
    '''
    
    class Poker():
     '''
     一张牌
     '''
    
     def __init__(self, num, type):
     self.num = num # 牌数
     self.type = type # 花色
    
    
    class GamePoker():
     '''
     一手牌,即5张Poker
     '''
     COMMON_NIU = 1 # 普通的牛,即牛一-牛七
     NO_NIU = 0 # 没有牛
     EIGHT_NINE_NIU = 2 # 牛九或牛八
     TEN_NIU = 3 # 牛十
     THREE_SAME = 4 # 三条
     FOUR_SAME = 5 # 四条
    
     def __init__(self, pokers):
     assert len(pokers) == 5
     self.pokers = pokers
     self.num_pokers = [p.num for p in self.pokers]
     # self.weight = None # 牌的权重,权重大的牌胜
     # self.money_weight = None # 如果该牌赢,赢钱的权重
     self.result = self.sumary()
    
     def is_niu(self):
     '''
     是否有牛
     :return:
     '''
     # if self.is_three_same():
     # return 0
     for three in itertools.combinations(self.num_pokers, 3):
     if sum(three) % 10 == 0:
     left = copy(self.num_pokers)
     for item in three:
     left.remove(item)
     point = sum(left) % 10
     return 10 if point == 0 else point
    
     return 0
    
     def is_three_same(self):
     '''
     是否3条
     :return:
     '''
     # if self.is_four_same():
     # return 0
     count = Counter([p.num for p in self.pokers])
     for num in count:
     if count[num] == 3:
     return num
     return 0
    
     def is_four_same(self):
     '''
     是否4条
     :return:
     '''
     count = Counter([p.num for p in self.pokers])
     for num in count:
     if count[num] == 4:
     return num
     return 0
    
     def sumary(self):
     '''
     计算牌
     '''
     if self.is_four_same():
     return GamePoker.FOUR_SAME
     if self.is_three_same():
     return GamePoker.THREE_SAME
     niu_point = self.is_niu()
     if niu_point in (8, 9):
     return GamePoker.EIGHT_NINE_NIU
     elif niu_point == 10:
     return GamePoker.TEN_NIU
     elif niu_point > 0:
     return GamePoker.COMMON_NIU
     else:
     return GamePoker.NO_NIU
    
    def get_all_pokers():
     '''
     生成所有的Poker,共四十个
     :return:
     '''
     pokers = []
     for i in range(1, 11):
     for j in ('A', 'B', 'C', 'D'):
     pokers.append(Poker(i, j))
    
     return pokers
    
    
    def get_all_game_poker(is_new=0):
     '''
     生成所有game_poker
     :param pokers:
     :return:
     '''
     pokers = get_all_pokers()
     game_pokers = []
    
     if not is_new and os.path.exists('game_pokers'):
     with open('game_pokers', 'r') as f:
     return cPickle.loads(f.read())
    
     for pokers in itertools.combinations(pokers, 5): # 5代表五张牌
     game_pokers.append(GamePoker(pokers))
     with open('game_pokers', 'w') as f:
     f.write(cPickle.dumps(game_pokers))
     return game_pokers
    
    
    def print_rate(game_pokers):
     total_num = float(len(game_pokers))
     four_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.FOUR_SAME])
     three_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.THREE_SAME])
     ten_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.TEN_NIU])
     eight_nine_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.EIGHT_NINE_NIU])
     common_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.COMMON_NIU])
     no_num = len([game_poker for game_poker in game_pokers if game_poker.result == GamePoker.NO_NIU])
     print '所有牌的组合数:%d' % total_num
     print '出现四条的组合数:%d,概率 :%.2f%%' % (four_num, four_num * 100 / total_num)
     print '出现三条的组合数:%d,概率 :%.2f%%' % (three_num, three_num * 100 / total_num)
     print '出现牛十的组合数:%d,概率 :%.2f%%' % (ten_num, ten_num * 100 / total_num)
     print '出现牛九或牛八的组合数:%d,概率 :%.2f%%' % (eight_nine_num, eight_nine_num * 100 / total_num)
     print '出现牛一到牛七的组合数:%d,概率 :%.2f%%' % (common_num, common_num * 100 / total_num)
     print '出现没有牛的组合数:%d,概率 :%.2f%%' % (no_num, no_num * 100 / total_num)
    
    
    def main():
     game_pokers = get_all_game_poker() # 658008种
     print_rate(game_pokers)
    
    
    main()
    

    下载本文
    显示全文
    专题