用R語言生成隨機數模擬鬥地主
阿新 • • 發佈:2018-12-30
程式介紹(Part A)
鬥地主中有時候會發現自己某一張牌沒有,比如J一張都沒抓到,下面使用R語言生成隨機數,模擬計算如果自己J一張都沒抓到的情況下,其他兩人抓到J炸的概率為0.104
iterSum = 1000000 #總實驗次數 countlostOneCard = rep(0,14) countBomb = rep(0,14) puke<- c(rep(1:13,4),"A","B")#1-13對應A,2,3,4..J,Q,K;A和B對應大小王 tmp <- c() for(iter in 1:iterSum){ player1.index<- sample(1:54,size=18,replace=FALSE) player1 <- puke[player1.index] otherpuke<- puke[!1:length(puke) %in% player1.index] player2.index<- sample(1:36,size=18,replace=FALSE) player2 <- otherpuke[player2.index] player3<- otherpuke[!1:length(otherpuke) %in% player2.index] #以上為隨機發牌 countLost <- c() for(i in seq(1:13)){ countLost <- c(countLost,i %in% player1)#檢視是否缺一張牌,即是否缺A,2,3,4..J,Q,K; } for(k in 0:13){ if(sum(countLost)==(13-k)){#如果缺k張牌 countlostOneCard[k+1] = countlostOneCard[k+1] + 1 BombFlag = FALSE #以下檢視對方兩家是否有炸彈(不包括王炸) for(j in seq(1:13)){ if(sum(j == player2)==4){# || ("A" %in% player2 && "B" %in% player2 BombFlag = TRUE } if(sum(j == player3)==4){# || ("A" %in% player3 && "B" %in% player3 BombFlag = TRUE } } if(BombFlag){ countBomb[k+1] = countBomb[k+1] + 1 } } } } # print("依次輸出自己缺k張牌的概率") print(countlostOneCard/iterSum) # print("在自己缺k張牌的時候,其他兩人有炸彈的概率") print(countBomb/countlostOneCard) # 結論 # 大致可以計算出,如果某個人沒拿到某張牌,例如9,剩下兩個人中某個人在這裡拿到9炸的概率為0.125 # 但是,因為每個人都拿18張牌,總拿到的牌數是一樣的,如果剩下兩個人在這裡拿了9炸(同時拿了4張),牌數(0,4)(4,0) # 總牌數一致導致拿牌數比計算出來的0.125要小 # 程式執行出來,剩下兩人出王炸的概率是0.104
執行結果(Part A)
> # print("依次輸出自己缺k張牌的概率") > print(countlostOneCard/iterSum) [1] 0.023521 0.161637 0.354045 0.315890 0.123036 0.020506 0.001338 0.000027 0.000000 0.000000 0.000000 [12] 0.000000 0.000000 0.000000 > # print("在自己缺k張牌的時候,其他兩人有炸彈的概率") > print(countBomb/countlostOneCard) [1] 0.0000000 0.1038809 0.1961643 0.2780272 0.3526122 0.4207549 0.4633782 0.4444444 NaN NaN [11] NaN NaN NaN NaN
程式介紹(Part B)
鬥地主中有時候會發現自己一張鬼牌都沒有,下面使用R語言生成隨機數,模擬計算如果自己一張鬼牌都沒有的情況下,其他兩人抓到王炸的概率為0.48
iterSum = 10000 countlostOneCard = 0 countBomb = 0 puke<- c(rep(1:13,4),"A","B") tmp <- c() for(iter in 1:iterSum){ player1.index<- sample(1:54,size=18,replace=FALSE) player1 <- puke[player1.index] otherpuke<- puke[!1:length(puke) %in% player1.index] player2.index<- sample(1:36,size=18,replace=FALSE) player2 <- otherpuke[player2.index] player3<- otherpuke[!1:length(otherpuke) %in% player2.index] if(!"A" %in% player1 && !"B" %in% player1){ countlostOneCard = countlostOneCard + 1 BombFlag = FALSE if("A" %in% player2 && "B" %in% player2){ BombFlag = TRUE } if("A" %in% player3 && "B" %in% player3){ BombFlag = TRUE } if(BombFlag){ countBomb = countBomb + 1 } } } # print("依次輸出自己缺小丑牌的概率") print(countlostOneCard/iterSum) # print("在自己缺小丑牌的時候,其他兩人有王炸的概率") print(countBomb/countlostOneCard) # 結論 # 大致可以計算出,如果某個人沒拿到"A"和"B",剩下兩個人中某個人在這裡拿了王炸(同時拿了兩張)的概率為0.5 # 但是,因為每個人都拿18張牌,總拿到的牌數是一樣的,如果剩下兩個人在這裡拿了王炸(同時拿了兩張),牌數(0,2)(2,0) # 這樣的概率會比剩下兩個人在這裡各自拿了一張王(1,1)的概率要小 # 程式執行出來,剩下兩人出王炸的概率是0.48
執行結果
> # print("依次輸出自己缺小丑牌的概率")
> print(countlostOneCard/iterSum)
[1] 0.438
> # print("在自己缺小丑牌的時候,其他兩人有王炸的概率")
> print(countBomb/countlostOneCard)
[1] 0.4803653
Further
程式還有些許不足的地方,在於發牌的時候,地主應該是比另外兩人多3張牌,這點模擬的時候沒有考慮到。
也沒有進行概率的置信度的計算。