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