野球ルールの構築

とりあえずこちらの3つめのやり方でかいてみた。

library(MCMCpack)
batter <- rbind(c(0.71,0.20,0.06,0.01,0.02), # これをいろいろ振ってみる
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02),
                c(0.71,0.20,0.06,0.01,0.02)
               )

f<- function(r,batter,size){  #rは試合回数、batterは打率行列、sizeは用意する打数
score.vector<- rep(0,r)
hit.pattern<- c(0,1,2,3,4)
for(t in 1:r){

size<- size 
res<- rep(0,9*size)
batter.one  <- sample(hit.pattern,prob=batter[1,],size=size,replace=T)
batter.two  <- sample(hit.pattern,prob=batter[2,],size=size,replace=T)
batter.three<- sample(hit.pattern,prob=batter[3,],size=size,replace=T)
batter.four <- sample(hit.pattern,prob=batter[4,],size=size,replace=T)
batter.five <- sample(hit.pattern,prob=batter[5,],size=size,replace=T)
batter.six  <- sample(hit.pattern,prob=batter[6,],size=size,replace=T)
batter.seven<- sample(hit.pattern,prob=batter[7,],size=size,replace=T)
batter.eight<- sample(hit.pattern,prob=batter[8,],size=size,replace=T)
batter.nine <- sample(hit.pattern,prob=batter[9,],size=size,replace=T)

for(p in 1:size){
  res[(p-1)*9+1]<- batter.one[p] 
  res[(p-1)*9+2]<- batter.two[p] 
  res[(p-1)*9+3]<- batter.three[p] 
  res[(p-1)*9+4]<- batter.four[p] 
  res[(p-1)*9+5]<- batter.five[p] 
  res[(p-1)*9+6]<- batter.six[p] 
  res[(p-1)*9+7]<- batter.seven[p] 
  res[(p-1)*9+8]<- batter.eight[p] 
  res[(p-1)*9+9]<- batter.nine[p] 
}

#アウト3つごとに前から抽出
out<- 0
for(k in 1:(length(res))){
  if(res[k]==0){
  out<- out + 1
    if(out==3){
    one<- res[c(1:k)]
    }
    if(out==6){
    two<- res[c((length(one)+1):k)]
    } 
    if(out==9){
    three<- res[c((length(one)+length(two)+1):k)]
    }
    if(out==12){
    four<- res[c((length(one)+length(two)+length(three)+1):k)]
    }
    if(out==15){
    five<- res[c((length(one)+length(two)+length(three)+
                  length(four)+1):k)]
    }
    if(out==18){
    six<- res[c((length(one)+length(two)+length(three)+
                 length(four)+length(five)+1):k)]
    }
    if(out==21){
    seven<- res[c((length(one)+length(two)+length(three)+
                   length(four)+length(five)+length(six)+1):k)]
    }
    if(out==24){
    eight<- res[c((length(one)+length(two)+length(three)+
                   length(four)+length(five)+length(six)+
                   length(seven)+1):k)]
    }
    if(out==27){
    nine<- res[c((length(one)+length(two)+length(three)+
                  length(four)+length(five)+length(six)+
                  length(seven)+length(eight)+1):k)]
    }
  }
}
#one;two;three;four;five;six;seven;eight;nine
#行列として扱えるように、足りない要素を補充して行数をそろえる
m<- max(length(one),length(two),length(three),
        length(four),length(five),length(six),
        length(seven),length(eight),length(nine))
one<-   append(one,rep(0,m-length(one)))
two<-   append(two,rep(0,m-length(two)))
three<- append(three,rep(0,m-length(three)))
four<-  append(four,rep(0,m-length(four)))
five<-  append(five,rep(0,m-length(five)))
six<-   append(six,rep(0,m-length(six)))
seven<- append(seven,rep(0,m-length(seven)))
eight<- append(eight,rep(0,m-length(eight)))
nine<-  append(nine,rep(0,m-length(nine)))
inning<- rbind(one,two,three,four,five,six,seven,eight,nine)

score<- 0 #まずは0点から
base.pattern<- 1 #まずは走者無
  for(i in 1:nrow(inning)){
  base.pattern<- 1 #イニングの始めは走者無から
    for(j in 1:ncol(inning)){ #そのイニングの先頭打者から、ダミーで増やしたアウト打者全部についてループ
      switch(base.pattern, #走者パターンで分岐させ、その次に打撃パターンで分岐
             switch(inning[i,j],
                    (base.pattern<- 2) && (score<- score),
                    (base.pattern<- 6) && (score<- score),
                    (base.pattern<- 8) && (score<- score),
                    (base.pattern<- 1) && (score<- score + 1)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 3) && (score<- score),
                    (base.pattern<- 7) && (score<- score),
                    (base.pattern<- 8) && (score<- score + 1),
                    (base.pattern<- 1) && (score<- score + 2)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 5) && (score<- score),
                    (base.pattern<- 7) && (score<- score + 1),
                    (base.pattern<- 8) && (score<- score + 2),
                    (base.pattern<- 1) && (score<- score + 3)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 3) && (score<- score + 1),
                    (base.pattern<- 7) && (score<- score + 1),
                    (base.pattern<- 8) && (score<- score + 2),
                    (base.pattern<- 1) && (score<- score + 3)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 5) && (score<- score + 1),
                    (base.pattern<- 7) && (score<- score + 2),
                    (base.pattern<- 8) && (score<- score + 3),
                    (base.pattern<- 1) && (score<- score + 4)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 4) && (score<- score),
                    (base.pattern<- 6) && (score<- score + 1),
                    (base.pattern<- 8) && (score<- score + 1),
                    (base.pattern<- 1) && (score<- score + 2)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 4) && (score<- score + 1),
                    (base.pattern<- 6) && (score<- score + 2),
                    (base.pattern<- 8) && (score<- score + 2),
                    (base.pattern<- 1) && (score<- score + 3)
                   ),
             switch(inning[i,j],
                    (base.pattern<- 2) && (score<- score + 1),
                    (base.pattern<- 6) && (score<- score + 1),
                    (base.pattern<- 8) && (score<- score + 1),
                    (base.pattern<- 1) && (score<- score + 2)
                   )
            )
    }
  }
inning #各イニングの打撃結果がわかる
score  #最終的な得点

score.vector[t]<- score
} #for.t end
return(histogram(score.vector))
}


10000回試合したときの得点分布。
 
でもこれだと超低い確率でヒット続きまくりました〜ってときにまずい。
しかもこの子はswitch関数が大好きなんじゃな〜って雰囲気でまくり。
NKからの助言をもとに、ちょっと改変。

runner<- c()    # 走者ベクトル。末項から、一塁、二塁、三塁、四塁…まあ、つまりこれ以降本塁
s<- c(1)        # 一塁埋まる
d<- c(1,0)      # 二塁埋まる
t<- c(1,0,0)    # 三塁埋まる
hr<- c(1,0,0,0) # 全塁掃き出す

total.score<- rep(0,9)
for(i in 1:9){
  runner<- rep(0,4)
  out<- 0
  repeat{
  x<- sample(c(0,1,2,3,4),prob=c(0.71,0.20,0.06,0.01,0.02),size=1)
    if(x==0){
      out<- out + 1
    }
    if(out==3){
      break
    }
    switch(x,
           (runner<- append(runner,s)), # シングルヒット
           (runner<- append(runner,d)), # ツーベース
           (runner<- append(runner,t)), # スリーベース
           (runner<- append(runner,hr)) # ホームラン
          )
         
  }
  total.score[i]<- sum(runner[c(1:(length(runner)-3))])
}
print(total.score)
print(sum(total.score))

そもそも野球はヒットごとに塁上の走者を追い出す?掃き出す?操作と考えられるので、こうすればrunnerベクトルの末尾3項は塁上の走者パターン、それより上は掃き出された人数としてカウントできる。といいなぁ。