とりあえずこちらの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項は塁上の走者パターン、それより上は掃き出された人数としてカウントできる。といいなぁ。