一步步解析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中的控制流语句的知识点
Apr 14 Python
利用Python中的mock库对Python代码进行模拟测试
Apr 16 Python
python之Socket网络编程详解
Sep 29 Python
Python实现的计数排序算法示例
Nov 29 Python
python实现单向链表详解
Feb 08 Python
tensorflow入门之训练简单的神经网络方法
Feb 26 Python
Numpy数组的保存与读取方法
Apr 04 Python
django DRF图片路径问题的解决方法
Sep 10 Python
Python之两种模式的生产者消费者模型详解
Oct 26 Python
Python lambda表达式filter、map、reduce函数用法解析
Sep 11 Python
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
Jun 22 Python
baselines示例程序train_cartpole.py的ImportError
May 20 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
获得Google PR值的PHP代码
2007/01/28 PHP
php adodb连接mssql解决乱码问题
2009/06/12 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
2014年10个最佳的PHP图像操作库
2014/07/14 PHP
PHP单例模式是什么 php实现单例模式的方法
2016/05/14 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
2016/11/12 PHP
PHP implode()函数用法讲解
2019/03/08 PHP
Laravel基础_关于view共享数据的示例讲解
2019/10/14 PHP
TP - 比RBAC更好的权限认证方式(Auth类认证)
2021/03/09 PHP
Javascript入门学习资料收集整理篇
2008/07/06 Javascript
JQuery SELECT单选模拟jQuery.select.js
2009/11/12 Javascript
javascript 用记忆函数快速计算递归函数
2010/03/15 Javascript
js的逻辑运算符 ||
2010/05/31 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
2016/08/01 Javascript
深入理解javascript函数参数与闭包
2016/12/12 Javascript
jQury Ajax使用Token验证身份实例代码
2017/09/22 Javascript
详解React中setState回调函数
2018/06/14 Javascript
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
详解JavaScript栈内存与堆内存
2019/04/04 Javascript
JS原型和原型链原理与用法实例详解
2020/02/05 Javascript
[48:27]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
Python的GUI框架PySide的安装配置教程
2016/02/16 Python
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
python安装Scrapy图文教程
2017/08/14 Python
python实现飞机大战微信小游戏
2020/03/21 Python
pygame实现俄罗斯方块游戏(AI篇1)
2019/10/29 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
2019/12/10 Python
python入门之基础语法学习笔记
2020/02/08 Python
keras 读取多标签图像数据方式
2020/06/12 Python
加拿大领先的牛仔零售商:Bluenotes
2018/01/22 全球购物
高中生毕业学习总结的自我评价
2013/11/14 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
致创业您:正能量激励人心句子(48条)
2019/08/15 职场文书
什么是Python装饰器?如何定义和使用?
2022/04/11 Python