一步步解析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操作MongoDB基础知识
Nov 01 Python
为python设置socket代理的方法
Jan 14 Python
10种检测Python程序运行时间、CPU和内存占用的方法
Apr 01 Python
Python简单实现子网掩码转换的方法
Apr 13 Python
python版微信跳一跳游戏辅助
Jan 11 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
python 获取一个值在某个区间的指定倍数的值方法
Nov 12 Python
使用pyhon绘图比较两个手机屏幕大小(实例代码)
Jan 03 Python
在pycharm中创建django项目的示例代码
May 28 Python
使用Keras加载含有自定义层或函数的模型操作
Jun 10 Python
Python pickle模块常用方法代码实例
Oct 10 Python
matplotlib阶梯图的实现(step())
Mar 02 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
索尼SONY ICF-7600A(W)电路分析
2021/03/01 无线电
PHP+Mysql+jQuery实现发布微博程序 jQuery篇
2011/10/08 PHP
php安全配置 如何配置使其更安全
2011/12/16 PHP
安装ImageMagick出现error while loading shared libraries的解决方法
2014/09/23 PHP
实现PHP+Mysql无限分类的方法汇总
2015/03/02 PHP
使用WAMP搭建PHP本地开发环境
2017/05/10 PHP
使用Zttp简化Guzzle 调用
2017/07/02 PHP
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
javascript 获取图片尺寸及放大图片
2013/09/04 Javascript
jquery中 $.expr使用实例介绍
2014/06/09 Javascript
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
基于jQuery实现多层次的手风琴效果附源码
2015/09/21 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
2016/05/25 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
javascript判断回文数详解及实现代码
2017/02/03 Javascript
JavaScript中双符号的运算详解
2017/03/12 Javascript
详解让sublime text3支持Vue语法高亮显示的示例
2017/09/29 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
2018/04/03 Javascript
JS canvas绘制五子棋的棋盘
2020/05/28 Javascript
Vue中ref和$refs的介绍以及使用方法示例
2021/01/11 Vue.js
下载给定网页上图片的方法
2014/02/18 Python
Python编程之string相关操作实例详解
2017/07/22 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
pandas apply多线程实现代码
2020/08/17 Python
Python内置函数及功能简介汇总
2020/10/13 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
总经理职责
2013/12/22 职场文书
中介业务员岗位职责
2014/04/09 职场文书
代理协议书
2014/04/22 职场文书
2014年学雷锋活动总结
2014/06/26 职场文书
详解Nginx 工作原理
2021/03/31 Servers
Python图片检索之以图搜图
2021/05/31 Python
python单元测试之pytest的使用
2021/06/07 Python