解密大数据

作业-计算机模拟赌博概率

2017-08-05  本文已影响429人  pnjoe

进阶作业

用计算机模拟的方法研究赌博策略:

有初始赌资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 来写的。


软件界面
上一篇下一篇

猜你喜欢

热点阅读