Python3 歐拉計(jì)劃 問(wèn)題84 大富翁

EulerProject.png

更多問(wèn)題參見(jiàn)http://www.itdecent.cn/p/8c3ec805433d

84、大富翁

??大富翁的標(biāo)準(zhǔn)棋盤(pán)大致如下圖所示:

Monopoly.png

??從標(biāo)記有GO的方格出發(fā),擲兩個(gè)6面的骰子,并將所得的點(diǎn)數(shù)之和,作為本輪前進(jìn)的步數(shù)。如果不附加其它規(guī)則,玩家玩過(guò)很多輪以后,落在每一格上的概率應(yīng)該都接近2.5%。但是,由于G2J(入獄)、CC(寶箱卡)和CH(機(jī)會(huì)卡)的存在,這個(gè)概率分布會(huì)有所改變。
??除了落在G2J上,或者在CCCH上有可能抽到入獄卡之外,如果玩家連續(xù)3次都擲出兩個(gè)一樣的點(diǎn)數(shù),例如玩家連續(xù)三次擲出的分別是(3,3),(1,1),(5,5),則在第三次時(shí)不會(huì)前進(jìn)5+5=10步,而是直接入獄。
??游戲開(kāi)始時(shí),CCCH中的牌將被隨機(jī)打亂。當(dāng)一個(gè)玩家落在CCCH上時(shí),他們從CCCH卡中的最上方取一張牌并按照牌面意思前進(jìn),并將該牌再放回牌堆的最下方。寶箱卡和機(jī)會(huì)卡都各有16張牌,因?yàn)槲覀冎魂P(guān)心會(huì)影響到移動(dòng)的牌,其它牌無(wú)效。寶箱卡和機(jī)會(huì)卡的牌見(jiàn)下面:

  • 寶箱卡 (2張牌,其他14張無(wú)效):
    ??回到起點(diǎn)GO
    ??進(jìn)入監(jiān)獄JAIL
  • 機(jī)會(huì)卡 (10張牌,其他6張無(wú)效):
    ??回到起點(diǎn)GO
    ??進(jìn)入監(jiān)獄JAIL
    ??移動(dòng)到C1
    ??移動(dòng)到E3
    ??移動(dòng)到H2
    ??移動(dòng)到R1
    ??移動(dòng)到下一個(gè)R(鐵路公司)
    ??移動(dòng)到下一個(gè)R
    ??移動(dòng)到下一個(gè)U(公共服務(wù)公司)
    ??后退三步

??這道題主要考察停在某個(gè)特定方格上的概率。顯然,除了停在G2J上的可能性為0之外,停在CH格的可能性最小,因?yàn)橛?/8的概率玩家會(huì)移動(dòng)到另一格。這里不區(qū)分是被送進(jìn)監(jiān)獄還是恰好落在監(jiān)獄,而且不考慮需要擲出兩個(gè)相同的點(diǎn)數(shù)才能出獄的要求,而是假定進(jìn)入監(jiān)獄的第2輪就會(huì)自動(dòng)出獄。
??從起點(diǎn)GO開(kāi)始,將方格依次標(biāo)記00至39,我們可以將這些兩位數(shù)連接起來(lái)表示方格的序列。
??統(tǒng)計(jì)學(xué)上來(lái)說(shuō),3個(gè)停下概率最大的方格分別是:
????JAIL(6.24%):方格10
????E3(3.18%):方格24
????GO(3.09%):方格00。
這三個(gè)方格可以用一個(gè)6位數(shù)字串表示為:102400
??上面的可能性是在用兩個(gè)6面骰子的情況下得到的,現(xiàn)在改用兩個(gè)4面的骰子,求出3個(gè)停下概率最大的方格構(gòu)成的6位數(shù)字串。

Python3解答
import numpy as np
import random
#計(jì)算隨機(jī)數(shù)
def Comnum(num, count):#計(jì)算幾個(gè)幾面色子的隨機(jī)數(shù)
    numlist = []
    st = 0
    while st < count:
        numlist.append(random.randint(1, num))
        st += 1
    return numlist

#CH卡
chlist = list(np.array([0, 10, 11, 24, 39, 5, 99, 99, 999, 9999] +[99999] * 6)[random.sample(range(16), 16)])#99999代表無(wú)效牌,隨即洗牌
chdict ={7: [15, 12], 22: [25, 28], 36: [5, 12]}
#CC卡
bxlist = list(np.array([0, 10] +[99999] * 14)[random.sample(range(16), 16)])#99999代表無(wú)效牌,隨即洗牌
bxdict = [2, 17, 33]

#定義取卡放卡后的函數(shù)
def Card(exlist):
    return exlist[1:] + [exlist[0]]#取完牌,將牌放在最下面

#計(jì)數(shù)字典
countdict = {kk : 0 for kk in range(40)}#每個(gè)數(shù)字代表一個(gè)方格
#開(kāi)始模擬
start = 0
jailsign = 0
monitimes = 10000#模擬的次數(shù)
for moni in range(monitimes):
    #開(kāi)始隨機(jī)數(shù)
    randomlist = Comnum(4, 2)#計(jì)算2個(gè)4面色子的隨機(jī)數(shù)
    sezi = sum(randomlist)#計(jì)算前進(jìn)的步數(shù)
    if randomlist[0] == randomlist[1]:
        jailsign += 1
    else:
        jailsign = 0
    if jailsign >= 3:#連續(xù)三次擲出相同的點(diǎn)數(shù)
        countdict[10] += 1#JAIL
        start = 10
    else:
        busu = (sezi + start) % 40
        if busu == 30:#G2J
            countdict[10] += 1#JAIL
            start = 10
        else:
            if busu in bxdict:#CC card
                if bxlist[0] == 99999:#Stop Moving
                    countdict[busu] += 1
                    start = busu
                else:
                    countdict[bxlist[0]] += 1
                    start = bxlist[0]
                bxlist = Card(bxlist).copy()
            elif busu in chdict:#CH card
                if chlist[0] == 99:#next R
                    nnum = chdict[busu][0]
                elif chlist[0] == 999:#next U
                    nnum = chdict[busu][1]
                elif chlist[0] == 99999:#Stop Moving
                    nnum = busu
                elif chlist[0] == 9999:#Backward 3
                    nnum = busu - 3
                    if nnum == 33:#CC card
                        if bxlist[0] != 99999:  # Stop Moving
                            nnum = bxlist[0]
                        bxlist = Card(bxlist).copy()
                else:
                    nnum = chlist[0]
                countdict[nnum] += 1
                start = nnum
                chlist = Card(chlist).copy()
            else:
                countdict[busu] += 1
                start = busu

#選擇前n個(gè)最大的值,并且輸出字符串
def Str(exdict, N, M):
    sdict = sorted(exdict.items(), key = lambda x: x[1], reverse = True)
    ncount = 0
    strkey = ''
    while ncount < N:
        item = sdict[ncount]

        if len(str(item[0])) < 2:
            strkey += '0%s'%item[0]
            print('0%s :%.4f%%\n'%(item[0], exdict[item[0]] / M * 100))
        else:
            strkey += '%s' % item[0]
            print('%s :%.4f%%' % (item[0], exdict[item[0]] / M * 100))
        ncount += 1
    return strkey

print('模擬完畢后,每個(gè)方格的停留次數(shù):%s'%countdict)
print(Str(countdict, 3, monitimes))
答案:
模擬完畢后,每個(gè)方格的停留次數(shù):{0: 276, 1: 185, 2: 148, 3: 201, 4: 217, 5: 275, 6: 208, 7: 80, 8: 198, 9: 218, 10: 762, 11: 212, 12: 250, 13: 246, 14: 302, 15: 380, 16: 309, 17: 287, 18: 293, 19: 289, 20: 308, 21: 301, 22: 113, 23: 280, 24: 356, 25: 304, 26: 256, 27: 258, 28: 281, 29: 296, 30: 0, 31: 293, 32: 225, 33: 225, 34: 248, 35: 181, 36: 75, 37: 197, 38: 216, 39: 251}
#3個(gè)停下概率最大的方格:
10 :7.6200%
15 :3.8000%
24 :3.5600%
#6位數(shù)字串:
101524
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容