问题重述:

大多数赌场使用6副牌或8副牌玩这种游戏,以防止“数牌点”,在你的模拟中使用两副牌(共104张)。只有2位参与者,你和庄家。游戏开始时每人得到两张牌,对于牌面为2~10的牌,点数和面数相同;对于为人脸(J、Q、K)的牌,点数为10;牌面为A的牌,点数为1或者11.游戏的目的是得到总数尽量接近21点的牌,不得超过(超过称“爆了”),并使你得到的总点数多于庄家。

如果开始两张牌的总点数恰为21(A-10或A-人脸),称为21点,自动成为胜者(若你和庄家都得到21点,则为平局,你的赌注仍在台上)。靠21点赢时,付给你3赔2,即1.5赔1(1元赌注赢1.5元,且1元赌注仍保留)。

如果你和庄家都未得到21点,你想要多少张牌就可以取多少张牌,一次一张,使总数尽量接近21点,如果你超过了21点,就输了,游戏结束。一旦你对牌的点数满意,你就“打住”,然后庄家按照下列规则取牌:

当庄家牌的点数为17、18、19、20和21时,就打住。若庄家牌的点数小于或等于16,必然取牌。庄家总把A的点数记为11,除非这样使他或她爆了(这时A的点数记为1)。例如,庄家的A-6组合是17点,不是7点(庄家没有选择权),且庄家必须打住在17点上。而若庄家有A-4组合(15点),又拿了一张K,那么新的总点数是15,因为A回到点数1(使之不超过21点) ,庄家还要再取牌。

如果庄家超过21点,你就赢了(赢赌注的钱,每1元赌注赢1元)。如果庄家的总点数超过你,你将输掉全部赌注。如果庄家和你的总点数相同,为平局(你不输也不赢)。

赌场中这个游戏的刺激之处在于,庄家开始的两张牌一张明、一张暗,所以你不知道庄家牌地总点数,必须根据那张明牌赌一把。在这个项目模拟中你不用考虑这种情况,你需要做的是:用两副牌做12次游戏,你有无限的赌资,每次下赌2元。两副牌玩过一次之后,用两副新牌继续玩,这时记录你的得分,然后下一幅牌从0开始,输出是12个结果,你可以用平均数决定你的总成绩。

函数说明与实现:

get_the_card( a )

输入一个列表,返回一个整数。

这个函数可以随机地从总扑克牌列表(列表名为:desktop)中获取一张扑克牌,并将其从扑克牌列表desktop中删除(因为同一张扑克牌不能取两次)。返回新获取到的扑克牌的值。

def get_the_card(a):

'''

从桌面上获取一张扑克牌,并将其从扑克牌列表中删除。

输入一个列表,返回随机获取的扑克牌值。

'''

n = len(a)

if n == 0:

sys.exit(1)

rand_num = np.random.randint(0, n) # 从现有的扑克牌中随机抽取一张

num = a.pop(rand_num) # 弹出选中的那一张

return num

count_points( a )

输入一个列表,返回一个列表。

这个函数输入玩家手中的扑克牌列表。(列表名为:player_cards 和 banker_cards),返回玩家手中牌所代表分值的所有可能(列表),不同的可能是由于A牌既可以看成是1也可以看成是11造成的。例如玩家手中的牌是 [1, 1, 1] 那么所有可能为 [3, 13, 23, 33]。

def count_points(a):

'''

这个函数用于计算玩家手中的牌点数的所有可能

输入:输入一个列表

输出:输出一个列表

'''

i = 0

sum_points = list([sum(a)])

while(1 in a):

a.remove(1)

i = i+1

sum_points = sum_points + [sum_points[-1] + 10]

for k in range(i):

a.append(1)

return sum_points

whats_the_point (cards, k)

输入一个列表,一个整数,返回一个整数。这个函数调用了上面的函数。

如果点数超过21点则返回-2,如果点数刚好是21,返回-1,如果点数介于[0, 19]之间则直接返回点数。

这个函数输入的是玩家手中扑克牌的列表和一个阈值,返回玩家手中牌在阈值的条件下,最具有优势的点数。正如上面函数说明中叙述的那样,相同的牌可能代表不同的点数,阈值代表了玩家主观的判断,例如:玩家认为17点已经很大了不需要再抽牌了,也就是阈值取17,那么如果他手中的牌为 [1, 7], 那么这个玩家就不会继续抽牌了,如果阈值取为 19 那么这个玩家就会认为 [1, 7] 代表了18 那么他就可以继续抽牌期望点数超过19。

下图为主函数的流程图:

主函数流程图

def whats_the_point (cards, k):

'''

这个函数可以输出**玩家**最有可能的点数

输入:points:点数可能列表

k: 阈值

输出:返回最有可能的分数(整数)

'''

points = count_points(cards)

if(points[-1]

return points[-1]

elif(points[-1]>21):

if len(points)==1:

return points[-1]

points.pop(-1)

return whats_the_point (points, k)

elif(points[-1]>=k and points[-1]<=21):

return points[-1]

black_jack_game(k)

主函数,输入一个整数,返回一个整数(包括 -3, 3, 2,-2, 0)

这个函数调用了前三个函数,根据输入的阈值,返回一次游戏所得点数。

def black_jack_game(k):

# 初始化全部扑克牌,保存在列表中

desktop = [10]*32

for i in [1,2,3,4,5,6,7,8,9]:

desktop = desktop + [i]*8

# 初始的两张牌

banker_cards = list([get_the_card(desktop),get_the_card(desktop)])

player_cards = list([get_the_card(desktop),get_the_card(desktop)])

# print('第一次发牌时玩家手中的牌是', player_cards) # 检查点

# print('第一次发牌时庄家手中的牌是', banker_cards) # 检查点

banker_points = whats_the_point(banker_cards,k)

player_points = whats_the_point(player_cards,k)

# print('第一次发牌时玩家手中的牌是', player_cards) # 检查点

# print('第一次发牌时庄家手中的牌是', banker_cards) # 检查点

# print('第一次发牌时玩家的点数是', player_points) # 检查点

# print('第一次发牌时庄家的点数是', banker_points) # 检查点

# 判断是否获胜

if (banker_points == 21):

return -3

if (player_points == 21):

return 3

if(banker_points == 21 or(player_points == 21)):

return points

# 如果没有获胜则继续抽牌直到点数达到了k值

while True:

banker_cards = banker_cards + list([get_the_card(desktop)])

if(whats_the_point(banker_cards,k)>=k):

break

while True:

player_cards = player_cards + list([get_the_card(desktop)])

# print(player_cards) # 检查点

if(whats_the_point(player_cards,k)>=k):

# print('此时玩家手中的牌是', player_cards) # 检查点

# print('此时玩家手中的点数是', banker_cards) # 检查点

# print('此时玩家手中的点数是', whats_the_point(player_cards,k)) # 检查点

# print('此时庄家手中的点数是', whats_the_point(banker_cards,k)) # 检查点

break

if whats_the_point(player_cards,k)>21:

return -2

if whats_the_point(banker_cards,k)>21:

return 2

if whats_the_point(player_cards,k)

return -2

elif whats_the_point(player_cards,k)>whats_the_point(banker_cards,k):

return 2

elif whats_the_point(player_cards,k)==whats_the_point(banker_cards,k):

return 0

运行结果:

下表即为程序运行 12 次的运行结果:

运行结果

为了查看不同阈值对结果的影响设计了下面的程序:

point_list = []

sumPoint = 0

for k in range(1,22):

for i in range(0,1000):

sumPoint = sumPoint + black_jack_game(k)

point_list = point_list + [sumPoint]

我们对0到22的阈值分别取了1000次实验结果,实验结果如下图所示,x轴为阈值,y轴为1000次模拟实验结果的总和。从结果中可以看出阈值越小,胜利的概率越大。

不同阈值下的结果

python蒙特卡洛模拟_基于Python的21点游戏蒙特卡洛模拟相关推荐

  1. python商城系统_基于python的海鲜商城系统

    20006 基于python的海鲜商城系统 运行视频.代码等: 链接:https://pan.baidu.com/s/1tw4Qvtcuwt7ys36M7HvLSg 提取码:1589 复制这段内容后打 ...

  2. 基于python爬虫数据处理_基于Python爬虫的校园数据获取

    苏艺航 徐海蛟 何佳蕾 杨振宇 王佳鹏 摘要:随着移动时代的到来,只适配了电脑网页.性能羸弱的校园教务系统,已经不能满足学生们的移动查询需求.为此,设计了一种基于网络爬虫的高实用性查询系統.它首先通过 ...

  3. python 量化交易_基于Python的量化交易工具清单(上)

    -- Python量化工具清单 -- 以下内容来源于Wilson Freitas的Github项目"Awesome Quant".原文中包含了丰富的语言类别,但是后续介绍主要针对P ...

  4. python自动化测试开发_基于python的selenium2自动化测试从基础到实战(Python3、selenium2、自动化测试、web测试)...

    Selenium2是目前比较流行的一款针对web页面测试的自动化测试工具,他的前身是Selenium .Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozi ...

  5. python机器视觉教材_基于Python的机器视觉实验教学平台设计

    基于 Python 的机器视觉实验教学平台设计 韩志豪 ; 刘晓英 [期刊名称] <计算机测量与控制> [年 ( 卷 ), 期] 2020(028)003 [摘要] 针对机器视觉领域的学习 ...

  6. python 英语分词_基于Python NLTK库进行英文文本预处理

    文本预处理是要文本处理成计算机能识别的格式,是文本分类.文本可视化.文本分析等研究的重要步骤.具体流程包括文本分词.去除停用词.词干抽取(词形还原).文本向量表征.特征选择等步骤,以消除脏数据对挖掘分 ...

  7. python爬虫现状_基于Python的微博爬虫系统研究

    基于 Python 的微博爬虫系统研究 陈政伊 袁云静 贺月锦 武瑞轩 [摘 要] [摘 要]随着大数据时代到来,爬虫的需求呈爆炸式增长,以新浪微 博为代表的一系列社交应用蕴含着巨大的数据资源.以新浪 ...

  8. python cut函数_基于python cut和qcut的用法及区别详解

    我就废话不多说了,直接上代码吧: from pandas import Series,DataFrame import pandas as pd import numpy as np from num ...

  9. python编码尺寸_基于Python批量生成指定尺寸缩略图代码实例

    这篇文章主要介绍了基于Python批量生成指定尺寸缩略图代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最近我们商城上架的应用越来越丰富了. ...

  10. cv2 python 获取斑马线_基于python的opencv图像处理实现对斑马线的检测示例

    基本思路 斑马线检测通过opencv图像处理来进行灰度值转换.高斯滤波去噪.阈值处理.腐蚀和膨胀后对图像进行轮廓检测,通过判断车辆和行人的位置,以及他们之间的距离信息,当车速到超过一定阈值时并且与行人 ...

最新文章

  1. PAT(甲级)2019年冬季考试 7-4 Cartesian Tree
  2. day32-1 事件Event
  3. oracle11g sp 1503,Oracle11g操作ASM权限问题
  4. LeetCode 204. Count Primes
  5. SharePoint 2013 中代码创建列表查阅项字段
  6. 移位溢注:告别依靠人品的偏移注入
  7. 微信支付国庆消费数据出炉:门票交易增幅超8成 酒店行业交易增幅超7成
  8. Windows2000系统下载安装,怀念一下
  9. Makefile 编写规则
  10. linux安装intel无线网卡驱动,CentOS 命令行安装intel 2200bg无线网卡驱动
  11. Linux C 函数参考(日期时间) 作者: 出处:hur.cn 更新时间: 2007年01月29日
  12. 人工智能Java SDK:图片分类(支持imagenet数据集分类)
  13. Qt编写安防视频监控系统18-云台控制
  14. 如何获取优酷视频的通用代码?
  15. 【解决方案】adb无法连接雷电模拟器问题
  16. Win10杀死进程方式
  17. [转帖]AMD第三代锐龙处理器首发评测:i9已无力招架
  18. 访问需要排队,奇葩网站有木有?
  19. 一键复制php代码,PHP_php下批量挂马和批量清马代码,复制代码 代码如下:?php funct - phpStudy...
  20. 180512 tensorboard高维数据可视化

热门文章

  1. 简单实现UITableView索引功能(中英文首字母索引)(一) ByH罗
  2. Ubuntu安装Gems报错的解决办法
  3. (转)Kinect背景移除支持多人
  4. java单利模式写法
  5. 2.1.3码元、波特、速率、带宽
  6. Leetcode--96. 不同的二叉搜索树(java)
  7. js纯ajax,自动完成JS类(纯JS, Ajax模式)
  8. mybatis代码自动生成器_最近很火的文章自动生成器,python源码公开了(内附python代码)
  9. php date 有warning,PHP Warning: strtotime()错误解决办法
  10. 四位数码管秒表 c语言编程,4位共阴极数码管秒表设计仿真与程序