一步步解析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读取json文件并将数据插入到mongodb的方法
Mar 23 Python
python 二分查找和快速排序实例详解
Oct 13 Python
python如何通过实例方法名字调用方法
Mar 21 Python
Python基于sklearn库的分类算法简单应用示例
Jul 09 Python
python实现换位加密算法的示例
Oct 14 Python
对python调用RPC接口的实例详解
Jan 03 Python
python tkinter canvas 显示图片的示例
Jun 13 Python
简单介绍python封装的基本知识
Aug 10 Python
利用python实现周期财务统计可视化
Aug 25 Python
python使用sklearn实现决策树的方法示例
Sep 12 Python
python深copy和浅copy区别对比解析
Dec 26 Python
Django表单提交后实现获取相同name的不同value值
May 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 Ajax实现页面无刷新发表评论
2007/01/02 PHP
ThinkPHP查询返回简单字段数组的方法
2014/08/25 PHP
PHP实现截取中文字符串不出现?号的解决方法
2016/12/29 PHP
PHP实现发送微博消息功能完整示例
2019/12/04 PHP
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
2006/12/06 Javascript
jQuery中文入门指南,翻译加实例,jQuery的起点教程
2007/02/09 Javascript
仿163填写邮件地址自动显示下拉(无优化)
2008/11/05 Javascript
给html超链接设置事件不使用href来完成跳
2014/04/20 Javascript
创建、调用JavaScript对象的方法集锦
2014/12/24 Javascript
JS基于clipBoard.js插件实现剪切、复制、粘贴
2016/05/03 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
2017/04/13 Javascript
微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
2017/04/18 Javascript
详解ElementUI之表单验证、数据绑定、路由跳转
2017/06/21 Javascript
webpack打包react项目的实现方法
2018/06/21 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
关于JavaScript数组去重的一些理解汇总
2020/09/10 Javascript
[38:21]2014 DOTA2国际邀请赛中国区预选赛5.21 TongFu VS LGD-CDEC
2014/05/22 DOTA
Python备份Mysql脚本
2008/08/11 Python
Python的Flask框架中实现分页功能的教程
2015/04/20 Python
Python实现的根据IP地址计算子网掩码位数功能示例
2018/05/23 Python
Python自定义一个类实现字典dict功能的方法
2019/01/19 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
HTML5画渐变背景图片并自动下载实现步骤
2013/11/18 HTML / CSS
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
爱尔兰橄榄球店:Irish Rugby Store
2019/12/05 全球购物
怎么处理XML的中文问题
2015/03/26 面试题
致跳远、跳高运动员广播稿
2014/01/09 职场文书
《去年的树》教学反思
2014/04/11 职场文书
英语教育专业自荐信
2014/05/29 职场文书
节约用水标语
2014/06/11 职场文书
2014年国庆节演讲稿
2014/09/02 职场文书
大学生档案自我鉴定(2篇)
2014/10/14 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书