一步步解析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使用cPickle模块序列化实例
Sep 25 Python
Django框架下在URLconf中指定视图缓存的方法
Jul 23 Python
python @property的用法及含义全面解析
Feb 01 Python
Ubuntu下使用python读取doc和docx文档的内容方法
May 08 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
Python matplotlib画图与中文设置操作实例分析
Apr 23 Python
pytorch实现特殊的Module--Sqeuential三种写法
Jan 15 Python
解决django中form表单设置action后无法回到原页面的问题
Mar 13 Python
基于virtualenv创建python虚拟环境过程图解
Mar 30 Python
keras中的loss、optimizer、metrics用法
Jun 15 Python
python怎么判断模块安装完成
Jun 19 Python
Python实现粒子群算法的示例
Feb 14 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_SELF的安全问题
2009/09/05 PHP
PHP 实现的将图片转换为TXT
2015/10/21 PHP
对PHP依赖注入的理解实例分析
2016/10/09 PHP
轻轻松松学习JavaScript
2007/02/25 Javascript
基于jquery的划词搜索实现(备忘)
2010/09/14 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
批量修改标签css样式以input标签为例
2014/07/31 Javascript
JavaScript函数的一些注意要点小结及js匿名函数
2015/11/10 Javascript
jquery+css实现动感的图片切换效果
2015/11/25 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
用jmSlip编写移动端顶部日历选择控件
2016/10/24 Javascript
JS实现批量上传文件并显示进度功能
2017/06/27 Javascript
node.js爬取中关村的在线电瓶车信息
2018/11/13 Javascript
JavaScript实现图片的放大缩小及拖拽功能示例
2019/05/14 Javascript
Python实现SVN的目录周期性备份实例
2015/07/17 Python
Zabbix实现微信报警功能
2016/10/09 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
分析python切片原理和方法
2017/12/19 Python
python+pyqt5编写md5生成器
2019/03/18 Python
利用Python产生加密表和解密表的实现方法
2019/10/15 Python
Python基础之高级变量类型实例详解
2020/01/03 Python
PyTorch中 tensor.detach() 和 tensor.data 的区别详解
2020/01/06 Python
Python实现AI自动抠图实例解析
2020/03/05 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
一文带你掌握Pyecharts地理数据可视化的方法
2021/02/06 Python
python tkinter实现下载进度条及抖音视频去水印原理
2021/02/07 Python
CSS3 仿微信聊天小气泡实例代码
2017/04/05 HTML / CSS
html5使用canvas画三角形
2014/12/15 HTML / CSS
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
美国乡村商店:Plow & Hearth
2016/09/12 全球购物
巴黎欧莱雅法国官网:L’Oreal Paris
2019/04/30 全球购物
SmartBuyGlasses比利时:购买品牌太阳镜和眼镜
2019/08/09 全球购物
员工安全承诺书
2014/05/22 职场文书
师德师风自我评价范文
2014/09/11 职场文书
打架检讨书
2015/01/27 职场文书
python中的None与NULL用法说明
2021/05/25 Python