ボウリングの得点

MikuHatsune2017-01-04

ボウリングをした。珍しくストライクが2回連続で出たので、スコアは137点だった。
ボウリングの得点分布はどうなっているのか気になったが、実際のゲームから得点分布を描くといろいろググって出てくる。
適当にピンを倒すとき、どうなるかをシミュレーションしてみる。

毎回のチャンスで倒れるピンの本数がランダムのとき、平均90 本くらいになる。

 
本当ならば、10本のピンのパターンは2^{10}-1の1023 通りあって、各パターン同士の推移行列ができる。例えばスプリットはスペアを取るのが困難なので、7-10 スプリットなんかは1) 1本も倒せない、2) 7 だけ倒す、3) 10 だけ倒す、4) スペアを取る、が確率 0.293,0.4,0.4,0.007 とかそんな感じで推移確率を出せそう。

gen <- function(prob=NULL){
  score <- c(rep(list(rep(NA, 2)), 9), list(rep(NA, 3)))
  flag <- rep(NA, 12)
  for(i in 1:9){
    score[[i]][1] <- sample(0:10, size=1, prob=prob)
    if(score[[i]][1] != 10){
      score[[i]][2] <- sample(0:(10 - score[[i]][1]), size=1)
      if(sum(score[[i]]) == 10){
        flag[i] <- "P"
      }
    } else {
      flag[i] <- "T"
    }
  }
  i <- 10
  score[[i]][1] <- sample(0:10, size=1, prob=prob)
  if(score[[i]][1] != 10){
    score[[i]][2] <- sample(0:(10 - score[[i]][1]), size=1)
    if(sum(score[[i]], na.rm=TRUE) == 10){
      flag[i+1] <- "P"
      score[[i]][3] <- sample(0:10, size=1)
      if(score[[i]][3] == 10){
        flag[i+2] <- "T"
      }
    }
  } else {
    flag[i] <- "T"
    score[[i]][2] <- sample(0:10, size=1)
    if(score[[i]][2] != 10){
      score[[i]][3] <- sample(0:(10 - score[[i]][2]), size=1)
      if(sum(score[[i]][2:3] == 10)){
        flag[i+2] <- "P"
      }
    } else {
      flag[i+1] <- "T"
      score[[i]][3] <- sample(0:10, size=1)
      if(score[[i]][3] == 10){
        flag[i+2] <- "T"
      }
    }
  }
  return(list(score=score, flag=flag))
}


total <- function(obj){
  score <- obj$score
  flag <- obj$flag
  s <- unlist(score)
  names(s) <- c(rep(flag[1:9], each=2), tail(flag, 3))
  names(s) <- replace(names(s), names(s)[1:18] == "P" & gtools::odd(1:18), NA)
  s <- na.omit(s)
  total <- 0
  for(i in 1:(length(s) - 3 + sum(any(is.na(score[[10]]))))){
    if(is.na(names(s)[i])){
      total <- sum(total, s[i], na.rm=TRUE)
    } else if (names(s)[i] == "P"){
      total <- sum(total, s[i:(i+1)], na.rm=TRUE)
    } else {
      total <- sum(total, s[i:(i+2)], na.rm=TRUE)
    }
    #print(total)
  }
  total <- total + sum(tail(s, 3 - sum(any(is.na(score[[10]])))))
  return(total)
}

iter <- 30000
hoge <- replicate(iter, gen(), simplify=FALSE)
b <- sapply(hoge, total)
hist(b, probability=TRUE, xlab="Score", main="Distribution of bowling score", col=4, nclass=80)