下記のモノポリーについての記事の続きです。
下記の記事では、実は「カード」の効果が考慮されていませんでした。
モノポリーでは、チャンスカードと共同基金カードの2種類があり、ゲームを左右する大きな効果があります。
今回はその効果も含めてた計算を行い、どの都市が最も稼げるのかを計算しました。
目的
今度はカード (チャンス、共同基金) の効果を入れて、計算してみた。
なおカードはそれぞれ 16 枚ずつある。
また前回のプログラム中では牢屋で足踏しているときに牢屋に止まった数には入れていなかったが、今回は足踏も、 入った数として計算する。
つまり牢屋で 2 回足踏をすれば、その分だけ牢屋に止まったと数えるのである。
モデル
今回のモデルを示す。
チャンスカード、共同基金カードの二種類のカードを予め適当に並べ、カードのマスに止まる度に次のカードを見て、その効果を反映する。
ただし今回反映したカードの効果は移動カードのみである。
つまり牢屋へ飛ぶとか、 3 マス戻るとか、その類。
ルール上使用したカードは即座にカードの山札の一番下に潜り込ませる。
そのため、今回初期のカードの順番 は適当にしたが、何周もすれば、どのカードをどこのマスで引くかはランダムになるはずで、初期のカード順は ほとんど影響しないはずである。
数値計算に使用したプログラムソース(fortran)
以下にソースを載せる。
c モノポリのどのマスに一番コマが止まるかを計算する
c さらにそのコマで支払うお金も計算する
program monopoly
implicit none
real ran, ran1, ran2
real d1, d2, d, s, m, sold
integer i(3), seed, j, k, r
integer n(40), mon(40), seki
real card, kyoudou, chance
integer c1, c2
c1 = 1
c2 = 1
s=0.0
r = 4
call itime(i)
seed = i(3) * 131
ran= rand(seed)
do j=1, 40, 1
n(j) = 0
end do
open (1, file="out.data", status='replace')
open (3, file="ran.data", status='replace')
do j=0, 100000, 1
!ダイスを振る
ran = ran *1000.0 + 43.0 * real(j)**0.5
ran = rand(int(ran))
ran = ran *1000.0
ran1 = ran
d1 = mod(int(ran), 6) + 1 !一個目のダイス決定
ran = ran + 37.0 * real(j)**0.5
ran = rand(int(ran))
ran = ran *1000.0
ran2 = ran
d2 = mod(int(ran), 6) + 1 !二個目のダイス決定
d = d1 + d2
!ダイスを振った(d1, d2)。dはその合計、つまり進む数を決定
if (r>=2) then
s = s + d
m = mod(s, 40) + 1.0
n(int(m)) = n(int(m)) + 1
if (mod(m, 31)==0 ) then !mが「31:GO TO JAIL」を示してれば「11:JAIL」にいく。
s = s + 20.0
r = 0
end if
!牢屋に入ってなければコマがどこに進んだかを計算。ただし変数型はreal
sold = s
s = card(s, m, c1, c2)
if (sold/=s) then
m = mod(s, 40) + 1.0
if (mod(m, 11)==0) then
r = 0
else
n(int(m)) = n(int(m)) + 1
end if
end if
else if (d1 == d2) then !牢屋入っていれば、ゾロ目かどうかを判断
s = s + d !ゾロ目なら進む。
r = 2 !牢屋からもでる。
m = mod(s, 40) + 1.0
n(int(m)) = n(int(m)) + 1
if (mod(m, 30)==0 ) then
s = s + 20.0
r = 0
end if
sold = s
s = card(s, m, c1, c2)
if (sold/=s) then
m = mod(s, 40) + 1.0
if (mod(m, 11)==0) then
r = 0
else
n(int(m)) = n(int(m)) + 1
end if
end if
else !牢屋に入っていてかつゾロ目でなければ、進まずに牢屋に入った数を数える。
r = r + 1
m = mod(s, 40) + 1.0
n(int(m)) = n(int(m)) + 1
end if
write(1, "(2i10, 3f20.10, 2i10)") j, r, d, s, m, c1, c2
write(3, "(i10, 2f20.10)") j, ran1, ran2
end do
close(3)
close(1)
open(10, file="mon2.data", status='old')
do j=1, 40, 1
read(10,*) mon(j)
end do
close(10)
open(2, file="n.data", status='replace')
do j = 1, 40, 1
seki = n(j) * mon(j)
write(2, "(4i10)") j, n(j), mon(j), seki
end do
close(2)
end program monopoly
real function card(s, m, c1, c2)
implicit none
real s, m, ds
integer c1, c2
real kyoudou, chance
if ((m==3).or.(m==18).or.(m==34)) then !共同基金
ds = kyoudou(m, c1)
else if ((m==8).or.(m==23).or.(m==37)) then !チャンス
ds = chance(m, c2)
else !どちらでもない
ds = 0.0
end if
card = s + ds
end function card
real function kyoudou(m, c1)
implicit none
real m
integer c1
if (c1==1) then !刑務所に行く
if (m==3) then
kyoudou = 8.0
else if (m==18) then
kyoudou = 33
else if (m==34) then
kyoudou = 17
end if
else if (c1==2) then !GOに行く
if (m==3) then
kyoudou = 38.0
else if (m==18) then
kyoudou = 23.0
else if (m==34) then
kyoudou = 7.0
end if
else !なにもしない
kyoudou = 0.0
end if
if (c1 <= 15) then !カードを回す
c1 = c1 + 1
else
c1 = 1
end if
end function kyoudou
real function chance(m, c2)
implicit none
real m
integer c2
if (c2==1) then !3マス戻る
chance = 38.0
else if (c2==2) then !セントチャールズプレースへ進む
if (m==8) then
chance = 4.0
else if (m==23) then
chance = 29.0
else if (m==37) then
chance = 15.0
end if
else if (c2==3) then !ボードウォークへ進む
if (m==8) then
chance = 32.0
else if (m==23) then
chance = 17.0
else if (m==37) then
chance = 3.0
end if
else if (c2==4) then !刑務所へ進む
if (m==8) then
chance = 3.0
else if (m==23) then
chance = 28.0
else if (m==37) then
chance = 14.0
end if
else if (c2==5) then !リーディング鉄道へ進む
if (m==8) then
chance = 39.0
else if (m==23) then
chance = 23.0
else if (m==37) then
chance = 9.0
end if
else if (c2==6) then !イリノイへ進む
if (m==8) then
chance = 17.0
else if (m==23) then
chance = 2.0
else if (m==37) then
chance = 28.0
end if
else if (c2==7) then !GOへ進む
if (m==8) then
chance = 33.0
else if (m==23) then
chance = 18.0
else if (m==37) then
chance = 4.0
end if
else if (c2==8) then !次の鉄道会社に進む
if (m==8) then
chance = 8.0
else if (m==23) then
chance = 3.0
else if (m==37) then
chance = 9.0
end if
else if (c2==9) then !次の水道会社か電力会社に進む
if (m==8) then
chance = 5.0
else if (m==23) then
chance = 6.0
else if (m==37) then
chance = 16.0
end if
else if (c2==10) then !次の鉄道会社に進む
if (m==8) then
chance = 8.0
else if (m==23) then
chance = 3.0
else if (m==37) then
chance = 9.0
end if
else
chance = 0.0
end if
if (c2 <= 15) then !カードを回す
c2 = c2 + 1
else
c2 = 1
end if
end function chance
コード内の「<」は「<」と置き換えてください。
結果1
まずはカードがしっかり回っていることを示すために、プログラムを回し、カード番号を確かめる。
プログラム 中、カードには c1, c2 という変数をふっていて、この変数が 1 から始まり、一回カードを引くと 2 に変わり、次 第に増えて 16 まで来たら 1 に戻るようにしてある。
以下が結果である。
グラフからわかるように、おおよそ 200 回サイコロを振れば、使用したカードが一周 (つまり 16 枚使用) する。
この結果からカードはしっかり回っていることがわかる。
結果2
次にまた各都市を買うのに必要な費用をグラフにした。
いよいよ以下に止まった数の計算結果を示す。
次に「期待値」を示す。この値が実質的に、その都市が持つ価値、儲かるかどうかを表した値となる。
結果を見ると、明らかに右に行く方が儲かることがわかる。
これは止まる確率はどのマスも大して変わらない ために、初期投資金額の影響が出ている。
もっと詳しく見ていくと、「ボードウォークへ行く」というカードのお かげもあり、最後の都市ボードウォークの価値が高い。
ただ、その手前の都市の価値は低く、独占できたときには マスも多いグリーンの領域が儲かる可能性が高い。
他にはやはりカードの効果が効いて、イリノイの価値が周りより高い。
コメント