美文网首页解密大数据
作业-计算机模拟赌博概率

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

作者: pnjoe | 来源:发表于2017-08-05 21:09 被阅读429次

    进阶作业

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

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


    软件界面

    相关文章

      网友评论

        本文标题:作业-计算机模拟赌博概率

        本文链接:https://www.haomeiwen.com/subject/kypwlxtx.html