黒ひげ危機一発

作成日

2023年8月29日

 洗濯機が回ってる間、やることが無くて「黒ひげ危機一発」のシミュレーションをやってみた。 誰だったかは覚えてないが、学部1年生のサークル合宿の時に誰かが 「最初にやったら当たる確率が一番低いし、ますますその確率は増加するわけだから、一番手の勝率(?)が一番低い」 と言ったのを思い出した。 最初は「あ、そうか」とも思ったが、考えてみたら最初のプレイヤーが当たると次の人はトライもせずに負け(?)になるから、割りと公平ではないかとも思った。

 それでやってみた。100万回のシミュレーション。

 まずは、設計から。黒ひげ危機一発のシミュレーションのためには以下の要素を設定しとかないといけない。それは

 当たりの位置はランダムで決まるから、関数の引数として用いるのは穴の数(hole)とプレイヤーの数(player)、そしてシミュレーションの試行回数(n)である。 誰が当たるのかを特定するために以下のようなアルゴリズムを使う。

  1. 一様分布 (\(\mbox{Uniform}(1, \text{hole})\)) から一個 (ただし、1以上の整数) を抽出し、これを「当たり」とする。
  2. \(X \in \{1, 2, ..., \text{hole}\}\) からholeの数だけ無作為抽出する。ただし、一回抽出された数字は二度と選ばれない (非復元抽出)。これがプレイヤーが「短剣を差し込む順番」である。
  3. もし、当たりが1番の穴であり、順番のベクトルが(3, 4, 1, 5, 2)なら3番目のプレイヤーが当たることになる。
  4. ただし、通常のようにplayer < holeの場合、mod(当たりの位置、プレイヤーの数)番目のプレイヤーが当たる。 3の例で4人のプレイヤーがいるとすると、当たりが2番の穴である場合、当たりはベクトルの5番目である。mod(5, 4) = 1、つまり、1番目のプレイヤーが当たる。
  5. これをn回繰り返す。

以上のアルゴリズムをRで表現すると

kuro.sim <- function(hole = 24, player = 4, trial = 100){ #関数を定義する
    result <- rep(NA, trial) #結果を書き込むベクトルを用意
    for(i in 1:trial){
        kurohige <- seq(from = 1, to = hole, by = 1) #U(1, hole)の生成
        atari    <- sample(kurohige, 1) #当たりの指定
        sasikomi <- sample(kurohige, hole, rep = FALSE) #差し込みの順番
        
        if(match(atari, sasikomi) %% player == 0){     #atariをplayerで割って余りが0なら
            result[i] <- player} else{ #最後のプレイヤーが当たり、それ以外の場合は
            result[i] <- match(atari, sasikomi) %% player
            } #atariをplayerで割った余り番目のプレイヤーが当たる
    }
    
    return(table(result)) #結果を表形式で返す
}

 結果を確認してみよう。

ケース1: 24穴、4人、10万回試行

Kuro1 <- kuro.sim(hole = 24, player = 4, trial = 100000)
Kuro1
result
    1     2     3     4 
25014 24986 25121 24879 

 結果を見ると順番なんか関係なく、当たりの確率は全てのブレイヤーにおいて約25%、つまり2万5千回くらいである。黒ひげ危機一発って、わりと公平なゲームだな…

 でも、もし5人でやったら?7人でやったら?つまり、穴の数をプレイヤーの数で割って余りがある場合はどうなるか。せっかく関数も作ったからやってみよう。今回こそ100万回だ!

ケース2: 24穴、5人、100万回試行

Kuro2 <- kuro.sim(hole = 24, player = 5, trial = 1000000)
Kuro2
result
     1      2      3      4      5 
207372 208727 209611 208214 166076 

ケース3: 24穴、7人、100万回試行

Kuro3 <- kuro.sim(hole = 24, player = 7, trial = 1000000)
Kuro3
result
     1      2      3      4      5      6      7 
166755 166706 166899 125104 124205 124898 125433 

 5人の場合は5番目のプレイヤーが、7人の場合は4番目以降のプレイヤーが当たる確率が確実に下る。つまり、mod(hole, player)番目以降のプレイヤーが当たる確率が低い。