进阶作业
用计算机模拟的方法研究赌博策略:
有初始赌资100元,初始赌注1元,赢的概率是49%,赢了赚回1倍的赌注, 输的概率是51%,输了就失去1倍的赌注。
- 1、每次赌注不变,都是1元,研究下注次数和最终赢钱的概率关系。
- 2、如果每输一次,赌注翻倍,赢了赌注变回1元,研究赢钱的概率。
- 3、在2的基础上,增加退出机制,即赚到一定的钱或者输掉一定的钱,就不玩了,研究赢钱的概率。
导入模块
import scipy.stats
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from __future__ import division # 支持精确除法
import random;
%config InlineBackend.figure_format = 'retina'
np.random.seed(123) #置随机数种子
# 先模拟一个49%概率赢,51%概率输的函数
def rollDice():
roll = np.random.randint(1,101) #随机生成1~100之间的任一个整数
if roll < 50:
return True # 若随机出来的是1~49之间的数.则算赢
if roll >= 50:
return False # 若随机出来的是50~100之间的数.则算输
# 定义一个简单玩法,赌注不变的函数
def simple(funds, initial_wager, wager_count,Bettors=1):
'''
funds: 初始赌资金额;
initial_wager: 初始单次赌注;
wager_count: 打算玩多少局;
value: 钱包动态金额,用于存储目前有多少赌资.赢了钱往这个变量加钱,输了钱往这个变量扣钱.
wager: 当局下的赌注
'''
bettor = 1 # 投注者编号
winner = 0 # 记录赢钱的人数
loser = 0 # 记录输钱的人数
draw = 0 # 记录平局的人数
out_count = 0 # 记录输光钱的人数
data = pd.DataFrame(columns=['bettor','funds','win_count','lose_count','currentWager','income','V_add','I_ratio','out','win_p','lose_p'])
for i in range(Bettors):
value = funds
wager = initial_wager
wX=[0] #X轴
vY=[value] #Y轴
win_count = 0 # 存储赢的局数
lose_count = 0 # 存储输的局数
currentWager = 1 # 存储当前的第几局
out = False
while currentWager <= wager_count:
if rollDice(): # 如果真.表示单次赢了.
value += wager
win_count += 1
wX.append(currentWager)
vY.append(value)
else:
value -= wager
lose_count += 1
wX.append(currentWager)
vY.append(value)
if value <= 0:
print(bettor,'号投注者余额仅:',value,'元,不足下局的赌注:',wager,'元。被T出局.') #有出局者提示
plt.text(currentWager,value-1,'OUT',ha='center',va='top',fontsize=10)
out_count += 1
out = True
currentWager += 1 #出局者次数较正
break # 出局者不再进行循环
currentWager += 1
if value > funds:
winner += 1 #累计赢钱人数
elif value < funds:
loser += 1 #累计输钱人数
else:
draw += 1 #累计平局人数
plt.plot(wX,vY,label='simple' + str(bettor),alpha=0.4) # 逐位投注者画图输出
if (value-funds) > 0:
plt.text(wX[-1],vY[-1],'win '+ str(vY[-1]-funds),ha='center',va='bottom',fontsize=13)
elif (value-funds) < 0:
plt.text(wX[-1],vY[-1],'lose '+ str(vY[-1]-funds),ha='center',va='bottom',fontsize=13)
else:
pass
# 数据表格输出(下面这行代码花了我两天多的时间,问了助教polo才折腾出来的)
data.loc[i+1]=[bettor,funds,win_count,lose_count,currentWager-1,value,value-funds,(value-funds)/funds,out,win_count/(win_count+lose_count),lose_count/(win_count+lose_count)]
bettor += 1
# 图表文字输出
plt.title(str(Bettors)+'位投注者,'+'初始资金'+str(funds)+'元,单次赌注'+str(initial_wager)+'元,连玩'+str(wager_count)+'局,资金变化图 ('+str(winner)+'人赢 : '+str(loser)+'人输 : '+str(draw)+'人平局)',fontsize=20)
plt.ylabel('Accoun Value',fontsize=15)
plt.xlabel('Wager Count',fontsize=15)
plt.hlines(funds,0,wager_count,colors = "r", linestyles = "dashed",label="初始资金线")
#plt.hlines(0,0,wager_count,colors = "k", linestyles = "dashed",label="死亡线")
plt.legend(fontsize=12) # 显示图例
if out > 0: # 如果有半路出局的人.计算一下出局总人数.
print('有',out_count,'位投注者,半路输光了钱,被T出局。')
return data # 将数据表格传出函数外
plt.figure(figsize=(15,15))
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
data=simple(100,1,100,20)
plt.show()
data
# 定义一个赌注输了翻倍,赢了变回初始赌注的函数
def doubler(funds, initial_wager, wager_count,Bettors=1):
'''
funds: 初始赌资金额;
initial_wager: 初始单次赌注;
wager_count: 打算玩多少局;
value: 钱包动态金额,用于存储目前有多少赌资.赢了钱往这个变量加钱,输了钱往这个变量扣钱.
wager: 当局下的赌注
'''
bettor = 1 # 投注者编号
winner = 0 # 记录赢钱的人数
loser = 0 # 记录输钱的人数
draw = 0 # 记录平局的人数
out_count = 0 # 记录输光钱的人数
data = pd.DataFrame(columns=['bettor','funds','win_count','lose_count','currentWager','income','V_add','I_ratio','out','win_p','lose_p','last_bet'])
for i in range(Bettors):
value = funds
wager = initial_wager
wX=[0] #X轴
vY=[value] #Y轴
win_count = 0 # 存储赢的局数
lose_count = 0 # 存储输的局数
currentWager = 1 # 存储当前的第几局
last_bet = 0 # 存储最后一局的赌注
out = False
while currentWager <= wager_count:
if rollDice(): # 如果真.表示单次赢了.
value += wager
win_count += 1
wX.append(currentWager)
vY.append(value)
last_bet = wager
wager = initial_wager
else:
value -= wager
lose_count += 1
wX.append(currentWager)
vY.append(value)
last_bet = wager
wager *= 2
if value <= 0:
print(bettor,'号投注者输光了钱,还欠:',value,'元,最后一局的赌注:',wager/2,'元。被T出局.') #有出局者提示
plt.text(currentWager,value-1,'Dead',ha='center',va='top',fontsize=10)
out_count += 1
out = True
currentWager += 1 #出局者次数较正
break # 出局者不再进行循环
currentWager += 1
if value > funds:
winner += 1 #累计赢钱人数
elif value < funds:
loser += 1 #累计输钱人数
else:
draw += 1 #累计平局人数
plt.plot(wX,vY,label='doubler' + str(bettor),alpha=0.4) # 逐位投注者画图输出
if (value-funds) > 0:
plt.text(wX[-1],vY[-1],'win '+ str(vY[-1]-funds),ha='center',va='bottom',fontsize=13)
elif (value-funds) < 0:
plt.text(wX[-1],vY[-1],'lose '+ str(vY[-1]-funds),ha='center',va='bottom',fontsize=13)
else:
pass
# 数据表格输出(下面这行代码花了我两天多的时间,问了助教polo才折腾出来的)
data.loc[i+1]=[bettor,funds,win_count,lose_count,currentWager-1,value,value-funds,(value-funds)/funds,out,win_count/(win_count+lose_count),lose_count/(win_count+lose_count),last_bet]
bettor += 1
# 图表文字输出
plt.title(str(Bettors)+'位投注者,'+'初始'+str(funds)+'元,赌注'+str(initial_wager)+'元,输了翻倍,连玩'+str(wager_count)+'局,资金变化图 ('+str(winner)+'人赢 : '+str(loser)+'人输 : '+str(draw)+'人平局)',fontsize=20)
plt.ylabel('Accoun Value',fontsize=15)
plt.xlabel('Wager Count',fontsize=15)
plt.hlines(funds,0,wager_count,colors = "r", linestyles = "dashed",label="初始资金线")
plt.hlines(0,0,wager_count,colors = "k", linestyles = "dashed",label="死亡线")
plt.legend(fontsize=12) # 显示图例
if out > 0: # 如果有半路出局的人.计算一下出局总人数.
print('有',out_count,'位投注者,半路输光了钱,被T出局。')
return data # 将数据表格传出函数外
plt.figure(figsize=(15,15))
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
data2=doubler(100,1,100,20)
plt.show()
# 运行结果
2 号投注者输光了钱,还欠: -17 元,最后一局的赌注: 64.0 元。被T出局.
4 号投注者输光了钱,还欠: -27 元,最后一局的赌注: 64.0 元。被T出局.
5 号投注者输光了钱,还欠: -23 元,最后一局的赌注: 64.0 元。被T出局.
10 号投注者输光了钱,还欠: -13 元,最后一局的赌注: 64.0 元。被T出局.
11 号投注者输光了钱,还欠: -22 元,最后一局的赌注: 64.0 元。被T出局.
14 号投注者输光了钱,还欠: -18 元,最后一局的赌注: 64.0 元。被T出局.
17 号投注者输光了钱,还欠: -3 元,最后一局的赌注: 64.0 元。被T出局.
data2
# 定义一个赌注输了翻倍,羸了变回初始赌注,增加限制收益率退出机率的函数
def advanced(funds, initial_wager, wager_count,Bettors=1,percentage=0.2,):
'''
funds: 初始赌资金额;
initial_wager: 初始单次赌注;
wager_count: 打算玩多少局;
value: 钱包动态金额,用于存储目前有多少赌资.赢了钱往这个变量加钱,输了钱往这个变量扣钱.
wager: 当局下的赌注
'''
bettor = 1 # 投注者编号
winner = 0 # 记录赢钱的人数
loser = 0 # 记录输钱的人数
draw = 0 # 记录平局的人数
out_count = 0 # 记录输光钱的人数
data = pd.DataFrame(columns=['bettor','funds','win_count','lose_count','currentWager','income','V_add','I_ratio','out','win_p','lose_p','last_bet'])
for i in range(Bettors):
value = funds
wager = initial_wager
wX=[0] #X轴
vY=[value] #Y轴
win_count = 0 # 存储赢的局数
lose_count = 0 # 存储输的局数
currentWager = 1 # 存储当前的第几局
last_bet = 0 # 存储最后一局的赌注
out = False
while currentWager <= wager_count:
if rollDice(): # 如果真.表示单次赢了.
value += wager
win_count += 1
wX.append(currentWager)
vY.append(value)
last_bet = wager
wager = initial_wager
if value-funds >= funds*percentage:
print(bettor,'号投注者羸钱达到',percentage*100,'%.落袋为安,结束游戏.') #有赢钱走人提示
break
else:
value -= wager
lose_count += 1
wX.append(currentWager)
vY.append(value)
last_bet = wager
wager *= 2
if value <= 0:
print(bettor,'号投注者输光了钱,还欠:',value,'元,最后一局的赌注:',wager/2,'元。被T出局.') #有出局者提示
plt.text(currentWager,value-1,'Dead',ha='center',va='top',fontsize=10)
out_count += 1
out = True
currentWager += 1 #出局者次数较正
break # 出局者不再进行循环
currentWager += 1
if value > funds:
winner += 1 #累计赢钱人数
elif value < funds:
loser += 1 #累计输钱人数
else:
draw += 1 #累计平局人数
plt.plot(wX,vY,label='advanced' + str(bettor),alpha=0.4) # 逐位投注者画图输出
#plt.text(wX[-1],vY[-1],wX[-1],ha='center',va='bottom',fontsize=13)
# 数据表格输出(下面这行代码花了我两天多的时间,问了助教polo才折腾出来的)
data.loc[i+1]=[bettor,funds,win_count,lose_count,currentWager-1,value,value-funds,(value-funds)/funds,out,win_count/(win_count+lose_count),lose_count/(win_count+lose_count),last_bet]
bettor += 1
# 图表文字输出
plt.title(str(Bettors)+'人,'+'初始'+str(funds)+'元,赌注'+str(initial_wager)+'元,输了翻倍,收益≥'+str(percentage*100)+'%退出,连玩'+str(wager_count)+'局('+str(winner)+'人赢 : '+str(loser)+'人输 : '+str(draw)+'人平局)',fontsize=20)
plt.ylabel('Accoun Value',fontsize=15)
plt.xlabel('Wager Count',fontsize=15)
plt.hlines(funds,0,wager_count,colors = "r", linestyles = "dashed",label="初始资金线")
plt.hlines(0,0,wager_count,colors = "k", linestyles = "dashed",label="死亡线")
plt.legend(fontsize=12) # 显示图例
if out > 0: # 如果有半路出局的人.计算一下出局总人数.
print('有',out_count,'位投注者,半路输光了钱,被T出局。')
return data # 将数据表格传出函数外
plt.figure(figsize=(15,15))
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
data3=advanced(100,1,100,20,0.3)
plt.show()
# 运行结果
1 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
2 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
3 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
4 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
5 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
6 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
7 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
8 号投注者输光了钱,还欠: -4 元,最后一局的赌注: 64.0 元。被T出局.
9 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
10 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
11 号投注者输光了钱,还欠: -126 元,最后一局的赌注: 128.0 元。被T出局.
12 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
13 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
14 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
15 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
16 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
17 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
18 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
19 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
20 号投注者羸钱达到 30.0 %.落袋为安,结束游戏.
data3
相关阅读
初学python-函数
2018.6.9更新。
Sole_af82 2018.06.09 21:32
问:请问你最后这个制图是用什么软件做出来的啊?
答:我是用Anaconda Navigator软件里的Jupyter notebook 来写的。
软件界面
网友评论