ばば抜きのシミュレーション
夜中に目が覚めて,眠れないのでやってみた。答が違いそうなので,再検証が必要か。
sim = function(n.player = 3) { # プレーヤーの人数
check = function(x) { # ペアになるカードを除いて返す関数
y = table(x) %% 2
as.integer(names(y)[y != 0])
}
n = 53 %% n.player # カード配りをちょっとトリッキーに
m = 53 %/% n.player + (n != 0)
card = c(c(rep(1:13, 4), 14)[sample(53)], rep(NA, m*n.player-53))
player = apply(matrix(card, m, byrow=TRUE), 2, na.omit) # 各プレーヤーの持ち札
player = lapply(player, check) # 配り終えた後,各自でチェック
counter = 0
from = 1 # 1番目の人が2番目の人に引かれることから開始
repeat {
counter = counter+1
n.player = length(player) # 残っているプレーヤーの人数
if (n.player == 1) break
to = if (from == n.player) 1 else from+1 # 最後の人のカードは1番目の人が引く
z = player[[from]] # カードを引かれるプレーヤーの処理
v = z[sample(length(z), 1)] # 無作為に1枚引かれる
player[[from]] = setdiff(z, v) # 持ち札からなくなる
if (length(player[[from]]) == 0) { # 持ち札が0枚なら上がり
player[[from]] = NULL # プレーヤーをリストから消去
if (to != 1) to = to-1 # カードを引くプレーヤーの番号は繰り下がる(1でない場合)
}
player[[to]] = c(player[[to]], v) # カードを引いたプレーヤーの持ち札
player[[to]] = check(player[[to]]) # チェック
if (length(player[[to]]) == 0) { # 持ち札が0枚なら上がり
player[[to]] = NULL # プレーヤーをリストから消去
if (to > length(player)) to = length(player)
}
from = to
}
counter
}
x <- replicate(1000, sim(26))
hist(x, right=FALSE)
![](https://blogimg.goo.ne.jp/user_image/60/fe/95133993c7c7962ef43a92b3d554e686.png)