Entries

「酔っぱらいの模擬実験」

雑誌に載ってたVBScriptプログラムをRubyで写経した
"酔っぱらって千鳥足のお父さんが駅から自宅まで無事に帰れる確率を求める「酔っぱらいの模擬実験プログラム」を作ります。地図は10*10のマス目に区切られていて、お父さんは駅をスタート地点として1度に1マス進むとします。酔っぱらっているので進む方向はランダムです。線路や塀などの障害物があるので地図の外には出られないとします。地図の中には駅と自宅以外にバーと池があります。自宅にたどり着く前に、バーに入るか、池に落ちたら、無事に帰宅できなかったとします。"(日経ソフトウェア2016年1月号より)


・書いたやつ
#初期設定
x = 1 #現在位置・駅からスタート
y = 5
homex = 10 #自宅の位置
homey = 5
barx = 3 #バーの位置
bary = 3
pondx = 8 #池の位置
pondy = 8
homecount = 0 #自宅へ無事に帰れた回数
barcount = 0 #バーに入った回数
pondcount = 0 #池に落ちた回数
n = 0 #回数カウント

#前後左右に動く確率
go_forward = 0.5 #前に進む確率
go_right = 0.2 #右に進む確率
go_left = 0.2 #左に進む確率
#残りの確率で後進

while true
 r = rand
  if r < go_forward
   x = x + 1
  elsif r < (go_forward + go_right)
   y = y + 1
  elsif r < (go_forward + go_right + go_left)
   y = y - 1
  else
   x = x - 1
 end

 if x == 0
  x = x + 1
 elsif x == 11
  x = x - 1
 elsif y == 0
  y = y + 1
 elsif y == 11
  y = y -1
 end

 if x == barx && y == bary
  puts 'お父さんはバーに入りました'
  barcount = barcount + 1
  n = n + 1
 end

 if x == pondx && y == pondy
  puts 'お父さんは池に落ちました'
  pondcount = pondcount + 1
  n = n + 1
 end

 if x == homex && y == homey
  puts 'お父さんは無事に帰宅しました!'
  homecount = homecount + 1
  n = n + 1
 end

 if n == 100
  break
 end
end

#実験結果
home = homecount / n.to_f * 100
bar = barcount / n.to_f * 100
pond = pondcount / n.to_f * 100
puts '実験結果'
puts '無事に帰宅できた回数=' + home.to_s + '%'
puts 'バーに入った回数=' + bar.to_s + '%'
puts '池に落ちた回数=' + pond.to_s + '%'

・動かしたやつ
・1回目

お父さんは無事に帰宅しました!
(98行省略)
お父さんは無事に帰宅しました!
実験結果
無事に帰宅できた回数=99.0%
バーに入った回数=1.0%
池に落ちた回数=0.0%
・2回目
実験結果
無事に帰宅できた回数=98.0%
バーに入った回数=1.0%
池に落ちた回数=1.0%
・3回目
実験結果
無事に帰宅できた回数=98.0%
バーに入った回数=0.0%
池に落ちた回数=2.0%
・4回目
実験結果
無事に帰宅できた回数=99.0%
バーに入った回数=1.0%
池に落ちた回数=0.0%
・5回目
実験結果
無事に帰宅できた回数=89.0%
バーに入った回数=0.0%
池に落ちた回数=11.0%

・反省会
・小文字は変数、大文字は定数というのを知らなかったのでエラーが出まくってびっくりした。
・地図からはみでないようにする制御で If X < 1 Then X = 1 とかいうのがあったんだけど、Then知らないのでif文で突っ込んだ。Rubyでも使えるらしいけど知らないのでやめた。
・VBScriptはFor文でループさせてたけどFor文知らないのでWhileした。Whileしたのはいいけどbreak設定し忘れてお父さんが5万歩千鳥足で動くはめになった。
・お父さんが動いた数をカウントしてたので到着した回数に書き換えるなどした。
・確率の計算で負数が0になる、浮動小数点数が出せない、文字列とか整数とかTypeErrorいまいち理解できてない。
・全部写経してからRubyに改変したので全体の流れをトレスできて勉強になった、が、初手から謎挙動だらけでどこがダメなのかわからず結局イチからRubyで書き直した。エラーが出ず結果も出ずが一番困る。
・行き先を配列にして関数作ればもっと良くなりそうだけど配列も関数も不慣れなので避けた。
・if文とWhile文はすっと書けるようになったので若干進化したっぽい。
・写経わりとおもしろい。一からひねり出すより難易度低いのでオライリーで腹立ったら簡単なやつ探して写経するの良さそう。
・5回目お父さん池に落ちすぎてておもしろい。
関連記事

Appendix

浅野あわわ

PV

CURRENT MOON

SEARCH

EVENT LINK