一步步解析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中的sort方法使用详解
Jul 25 Python
Python IDE PyCharm的基本快捷键和配置简介
Nov 04 Python
SVM基本概念及Python实现代码
Dec 27 Python
详解通过API管理或定制开发ECS实例
Sep 30 Python
python2和python3的输入和输出区别介绍
Nov 20 Python
利用ctypes获取numpy数组的指针方法
Feb 12 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
详解Python文件修改的两种方式
Aug 22 Python
python装饰器原理与用法深入详解
Dec 19 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
python使用pyecharts库画地图数据可视化的实现
Mar 25 Python
如何使用 Flask 做一个评论系统
Nov 27 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
中国的第一台收音机
2021/03/01 无线电
PHP4实际应用经验篇(3)
2006/10/09 PHP
跟我学Laravel之配置Laravel
2014/10/15 PHP
php转换上传word文件为PDF的方法【基于COM组件】
2019/06/10 PHP
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
jQuery循环滚动展示代码 可应用到文字和图片上
2012/05/11 Javascript
Jquery插件写法笔记整理
2012/09/06 Javascript
document.createElement()用法
2013/03/13 Javascript
Javascript Throttle & Debounce应用介绍
2013/03/19 Javascript
在JavaScript中判断整型的N种方法示例介绍
2014/06/18 Javascript
Jqgrid之强大的表格插件应用
2015/12/02 Javascript
Vue.JS入门教程之事件监听
2016/12/01 Javascript
任意Json转成无序列表的方法示例
2016/12/09 Javascript
JS获取input[file]的值并显示在页面的实现方法
2018/03/09 Javascript
使用JSON格式提交数据到服务端的实例代码
2018/04/01 Javascript
JavaScript实现图片的放大缩小及拖拽功能示例
2019/05/14 Javascript
react国际化化插件react-i18n-auto使用详解
2020/03/31 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
2021/01/07 Vue.js
[58:00]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第二场 2月7日
2021/03/11 DOTA
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
Python中的赋值、浅拷贝、深拷贝介绍
2015/03/09 Python
python实现字符串和日期相互转换的方法
2015/05/13 Python
Python编程之event对象的用法实例分析
2017/03/23 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
使用python实现mqtt的发布和订阅
2019/05/05 Python
Python使用matplotlib绘制三维参数曲线操作示例
2019/09/10 Python
python 实现关联规则算法Apriori的示例
2020/09/30 Python
5个你不知道的HTML5的接口介绍
2013/08/07 HTML / CSS
什么是WEB控件?使用WEB控件有哪些优势?
2012/01/21 面试题
应届本科生推荐信范文
2013/12/25 职场文书
团支书竞选演讲稿
2014/04/28 职场文书
社保代办委托书怎么写
2014/10/06 职场文书
后勤工作个人总结
2015/02/28 职场文书
《1942》观后感
2015/06/08 职场文书
让世界充满爱观后感
2015/06/10 职场文书
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS