一步步解析Python斗牛游戏的概率


Posted in Python onFebruary 12, 2016

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

  • 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()

以上就是Python计算斗牛游戏的概率相关内容,希望对大家的学习有所帮助。

Python 相关文章推荐
巧用python和libnmapd,提取Nmap扫描结果
Aug 23 Python
python用模块zlib压缩与解压字符串和文件的方法
Dec 16 Python
Scrapy-redis爬虫分布式爬取的分析和实现
Feb 07 Python
Python中字符串格式化str.format的详细介绍
Feb 17 Python
python生成词云的实现方法(推荐)
Jun 13 Python
实时获取Python的print输出流方法
Jan 07 Python
python 将对象设置为可迭代的两种实现方法
Jan 21 Python
python3 打印输出字典中特定的某个key的方法示例
Jul 06 Python
python中必要的名词解释
Nov 20 Python
pytorch中获取模型input/output shape实例
Dec 30 Python
Python如何使用字符打印照片
Jan 03 Python
Python面向对象编程之类的概念
Nov 01 Python
常用python编程模板汇总
Feb 12 #Python
python黑魔法之参数传递
Feb 12 #Python
python实现井字棋游戏
Mar 30 #Python
python搭建微信公众平台
Feb 09 #Python
Python实例一个类背后发生了什么
Feb 09 #Python
Python中的条件判断语句基础学习教程
Feb 07 #Python
Python模拟登录验证码(代码简单)
Feb 06 #Python
You might like
php检测mysql表是否存在的方法小结
2017/07/20 PHP
js 无提示关闭浏览器页面的代码
2010/03/09 Javascript
有关js的变量作用域和this指针的讨论
2010/12/16 Javascript
原生js实现查找/添加/删除/指定元素的class
2013/04/12 Javascript
jquery next nextAll nextUntil siblings的区别介绍
2013/10/05 Javascript
javascript中直接引用Microsoft的COM生成Word
2014/01/20 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
Nginx上传文件全部缓存解决方案
2015/08/17 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
2016/02/21 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
JavaScript实现数组降维详解
2017/01/05 Javascript
Node.js 进程平滑离场剖析小结
2019/01/24 Javascript
在 Vue.js中优雅地使用全局事件的方法
2019/02/01 Javascript
Vue渲染过程浅析
2019/03/14 Javascript
在vue中使用防抖和节流,防止重复点击或重复上拉加载实例
2019/11/13 Javascript
从表单校验看JavaScript策略模式的使用详解
2020/10/17 Javascript
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
机器学习10大经典算法详解
2017/12/07 Python
浅谈Pycharm中的Python Console与Terminal
2019/01/17 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
django 中使用DateTime常用的时间查询方式
2019/12/03 Python
jupyter notebook 多行输出实例
2020/04/09 Python
python操作链表的示例代码
2020/09/27 Python
世界上最大的糖果店:Dylan’s Candy Bar
2017/11/07 全球购物
Falconeri美国官网:由羊绒和羊毛制成的针织服装
2018/04/08 全球购物
荷兰音乐会和音乐剧门票订购网站:Topticketshop
2019/08/27 全球购物
加拿大鞋网:Globo Shoes
2019/12/26 全球购物
下列程序在32位linux或unix中的结果是什么
2015/01/26 面试题
Java编程面试题
2016/04/04 面试题
物业管理员岗位职责范文
2013/11/25 职场文书
公司请假条格式
2014/04/11 职场文书
晋江市人民政府党组群众路线教育实践活动整改方案
2014/10/25 职场文书
四年级作文之说明文作文
2019/10/14 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
前端监听websocket消息并实时弹出(实例代码)
2021/11/27 Javascript