一步步解析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程序抓取网页的HTML信息的一个小实例
May 02 Python
python类继承用法实例分析
May 27 Python
Python中map,reduce,filter和sorted函数的使用方法
Aug 17 Python
Python通过DOM和SAX方式解析XML的应用实例分享
Nov 16 Python
Tornado协程在python2.7如何返回值(实现方法)
Jun 22 Python
把csv文件转化为数组及数组的切片方法
Jul 04 Python
Python subprocess库的使用详解
Oct 26 Python
Win 10下Anaconda虚拟环境的教程
May 18 Python
浅谈Python 函数式编程
Jun 20 Python
Python爬取某平台短视频的方法
Feb 08 Python
Python基础知识之变量的详解
Apr 14 Python
pd.DataFrame中的几种索引变换的实现
Jun 16 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动态创建Flash动画
2006/10/09 PHP
别人整理的服务器变量:$_SERVER
2006/10/20 PHP
php getsiteurl()函数
2009/09/05 PHP
PHP设计模式之迭代器模式的深入解析
2013/06/13 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
详解php伪造Referer请求反盗链资源
2019/01/24 PHP
Iframe自适应高度绝对好使的代码 兼容IE,遨游,火狐
2011/01/27 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
详解JSON1:使用TSQL查询数据和更新JSON数据
2016/11/21 Javascript
jQuery Checkbox 全选 反选的简单实例
2016/11/29 Javascript
Bootstrap下拉菜单样式
2017/02/07 Javascript
AngularJs 终极购物车(实例讲解)
2017/11/08 Javascript
Node.js readline模块与util模块的使用
2018/03/01 Javascript
p5.js入门教程之鼠标交互的示例
2018/03/16 Javascript
vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作
2020/08/03 Javascript
python基础教程之popen函数操作其它程序的输入和输出示例
2014/02/10 Python
Flask框架使用DBUtils模块连接数据库操作示例
2018/07/20 Python
python实现录音小程序
2020/10/26 Python
深入浅析python3中的unicode和bytes问题
2019/07/03 Python
python爬虫今日热榜数据到txt文件的源码
2021/02/23 Python
详解基于 Canvas 手撸一个六边形能力图
2019/09/02 HTML / CSS
兰蔻加拿大官方网站:Lancome加拿大
2016/08/05 全球购物
日本7net购物网:书籍、漫画、杂志、DVD、游戏邮购
2017/02/17 全球购物
The North Face北面英国官网:美国著名户外品牌
2017/12/13 全球购物
安德玛加拿大官网:Under Armour加拿大
2019/10/02 全球购物
Penhaligon’s英国官网:成立于1870年的英国香水制造商
2021/02/18 全球购物
医务人员竞聘职务自我评价分享
2013/11/08 职场文书
亮化工程实施方案
2014/03/17 职场文书
酒店总经理岗位职责
2014/03/17 职场文书
公司年底活动方案
2014/08/17 职场文书
普通话演讲稿
2014/09/03 职场文书
教师工作总结范文2014
2014/11/10 职场文书
2014年食堂工作总结
2014/11/20 职场文书
师德先进个人材料
2014/12/20 职场文书
社团个人总结范文
2015/03/05 职场文书
护士长2015年终工作总结
2015/04/24 职场文书