[Python勉強記録 #02]チンチロの期待値計算

Python

[初めに]

当初の目的であったチンチロの期待値計算をPythonを用いて行ったので、その記録を残します。

基礎を少し勉強した後、すぐに計算に取り掛かったため上手くコードが書けていないと思うのですが、実践あるのみと思い挑戦してみました。結果としては期待値を求めることはでき目標を達成することができたので初めにしては良かったと思います。

[コード]

入力コード

# 条件 親と子が同じ役の場合親の勝ち
#      役が出るまで3回振る

#最初に役の確率
#それぞれの確率
p_pin = 1 / 216
p_666 = 1 / 216
p_555 = 1 / 216
p_444 = 1 / 216
p_333 = 1 / 216
p_222 = 1 / 216
p_456 = 1 / 36
p_6 = 15 / 216
p_5 = 15 / 216
p_4 = 15 / 216
p_3 = 15 / 216
p_2 = 15 / 216
p_1 = 15 / 216
p_123 = 1 / 36
p_0 = 108 / 216


#役と確率の辞書
p_list = {"p_pin": 1 / 216, "p_666": 1 / 216, "p_555": 1 / 216, "p_444": 1 / 216, "p_333": 1 / 216, "p_222": 1 / 216, "p_456": 1 / 36, 
          "p_6": 15 / 216, "p_5": 15 / 216, "p_4": 15 / 216, "p_3": 15 / 216, "p_2": 15 / 216, "p_1": 15 / 216,
          "p_123": 1 / 36, "p_0": 108 /216}


#確認のため確率の合計
sum_p = sum(p_list.values())
print(sum_p)


#3回投げた時の確率
p1_pin = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_666 = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_555 = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_444 = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_333 = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_222 = (1 / 216) + ((108 / 216) * (1 / 216)) + ((108 / 216) ** 2 * (1 / 216))
p1_456 = (1 / 36) + ((108 / 216) * (1 / 36)) + ((108 / 216) ** 2 * (1 / 36))
p1_6 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_5 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_4 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_3 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_2 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_1 = (15 / 216) + ((108 / 216) * (15 / 216)) + ((108 / 216) ** 2 * (15 / 216))
p1_123 = (1 / 36) + ((108 / 216) * (1 / 36)) + ((108 / 216) ** 2 * (1 / 36))
p1_0 = (108 / 216) ** 3

print(round(p1_pin * 100, 2), round(p1_666 * 100, 2), round(p1_456 * 100, 2), round(p1_6 * 100, 2), round(p1_0 * 100, 2))


#確認のための確率の和
sum_p1 = (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 +
      p1_6 + p1_5 + p1_4 + p1_3 + p1_2 + p1_1 + p1_123 + p1_0)
print(sum_p1)


#3回の確率を使って親の勝つ確率を求める
p1w_pin = p1_pin
p1w_666 = p1_666 * (1 - p1_pin)
p1w_555 = p1_555 * (1 - (p1_pin + p1_666))
p1w_444 = p1_444 * (1 - (p1_pin + p1_666 + p1_555))
p1w_333 = p1_333 * (1 - (p1_pin + p1_666 + p1_555 + p1_444))
p1w_222 = p1_222 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333))
p1w_456 = p1_456 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222))
p1w_6 = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456))
p1w_5 = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6))
p1w_4 = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5))
p1w_3 = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5 + p1_4))
p1w_2  = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5 + p1_4 + p1_3))
p1w_1 = p1_1 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5 + p1_4 + p1_3 + p1_2))
p1w_123 = p1_123 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5 + p1_4 + p1_3 + p1_2 + p1_1))
p1w_0 = p1_0 * (1 - (p1_pin + p1_666 + p1_555 + p1_444 + p1_333 + p1_222 + p1_456 + 
                     p1_6 + p1_5 + p1_4 + p1_3 + p1_2 + p1_1 + p1_123))

#親の勝つ確率
print(round(p1w_pin * 100, 2), round(p1w_666 * 100, 2), round(p1w_555 * 100, 2), round(p1w_444 * 100, 2), 
      round(p1w_333 * 100, 2), round(p1w_222 * 100, 2), round(p1w_456 * 100, 2), round(p1w_6 * 100, 2), 
      round(p1w_5 * 100, 2), round(p1w_4 * 100, 2), round(p1w_3 * 100, 2), round(p1w_2 * 100, 2), 
      round(p1w_1 * 100, 2), round(p1w_0 * 100, 2), round(p1w_123 * 100, 2))

sum_p1w = (p1w_pin + p1w_666 + p1w_555 + p1w_444 + p1w_333 + p1w_222 + p1w_456 +
      p1w_6 + p1w_5 + p1w_4 + p1w_3 + p1w_2 + p1w_1 + p1w_123 + p1w_0)

print("親の勝つ確率:" + str(round(sum_p1w * 100, 2)) + "%")


#役ごとに期待値を求める(分かりやすく1000円かけた時を想定)
p1e_pin = (p1_pin * (((1 - p1_123) * 5) + (p1_123 * 10)) * 1000)
p1e_666 = (p1_666 * (((p1_pin) * (-5)) + ((1 - (p1_pin + p1_123)) * 3) + ((p1_123) * 6)) * 1000)
p1e_555 = (p1_555 * (((p1_pin) * (-5)) + ((p1_666) * (-3)) + ((1 - (p1_pin + p1_666 + p1_123)) * 3) + ((p1_123) * 6)) * 1000)
p1e_444 = (p1_444 * (((p1_pin) * (-5)) + ((p1_666 * 2) * (-3)) + ((1 - (p1_pin + (p1_666 * 2) + p1_123)) * 3) + ((p1_123) * 6)) * 1000)
p1e_333 = (p1_333 * (((p1_pin) * (-5)) + ((p1_666 * 3) * (-3)) + ((1 - (p1_pin + (p1_666 * 3) + p1_123)) * 3) + ((p1_123) * 6)) * 1000)
p1e_222 = (p1_222 * (((p1_pin) * (-5)) + ((p1_666 * 4) * (-3)) + ((1 - (p1_pin + (p1_666 * 4) + p1_123)) * 3) + ((p1_123) * 6)) * 1000)
p1e_456 = (p1_456 * (((p1_pin) * (-5)) + ((p1_666 * 5) * (-3)) + ((1 - (p1_pin + (p1_666 * 5) + p1_123)) * 2) + ((p1_123) * 4)) * 1000)
p1e_6 = (p1_6 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 6) + p1_0) + (p1_123 * 2)) * 1000)
p1e_5 = (p1_5 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6) * (-1)) + ((p1_6 * 5) + p1_0) + (p1_123 * 2)) * 1000)
p1e_4 = (p1_4 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 2) * (-1)) + ((p1_6 * 4) + p1_0) + (p1_123 * 2)) * 1000)
p1e_3 = (p1_3 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 3) * (-1)) + ((p1_6 * 3) + p1_0) + (p1_123 * 2)) * 1000)
p1e_2 = (p1_2 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 4) * (-1)) + ((p1_6 * 2) + p1_0) + (p1_123 * 2)) * 1000)
p1e_1 = (p1_1 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 5) * (-1)) + ((p1_6 * 1) + p1_0) + (p1_123 * 2)) * 1000)
p1e_123 = (p1_123 * (((p1_pin) * (-10)) + (p1_666 * 5 * (-6)) + (p1_456 * (-4)) + (((p1_6 * 6) + p1_0) * (-2)) + (p1_123 * 2)) * 1000)
p1e_0 = (p1_0 * (((p1_pin) * (-5)) + (p1_666 * 5 * (-3)) + (p1_456 * (-2)) + ((p1_6 * 6) * (-1)) + (p1_0) + (p1_123 * 2)) * 1000)

print(round(p1e_pin, 2), round(p1e_666, 2), round(p1e_555, 2), round(p1e_444, 2), round(p1e_333, 2), round(p1e_222, 2), 
      round(p1e_456, 2), round(p1e_6, 2), round(p1e_5, 2), round(p1e_4, 2), round(p1e_3, 2), round(p1e_2, 2), 
      round(p1e_1, 2), round(p1e_0, 2), round(p1e_123, 2))

sum_p1e = (p1e_pin + p1e_666 + p1e_555 + p1e_444 + p1e_333 + p1e_222 + p1e_456 +
           p1e_6 + p1e_5 + p1e_4 + p1e_3 + p1e_2 + p1e_1 + p1e_123 + p1e_0)

print("親の期待値:" + str(round(sum_p1e)) + "円")


#還元率で考える
#1000円賭けて親が115円の期待値なので子は1000円かけて885円の期待値になる。よって、還元率は
back_rate = 885 / 1000 * 100
print("還元率:" + str(round(back_rate)) + "%")

出力結果
1.0
0.81 0.81 4.86 12.15 12.5
1.0
0.81 0.8 0.8 0.79 0.78 0.78 4.62 10.97 9.49 8.02 6.54 5.06 3.59 1.56 0.84
親の勝つ確率:55.47%
42.48 24.96 24.57 24.17 23.78 23.39 89.35 84.11 54.57 25.04 -4.5 -34.04 -63.58 -95.78 -103.52
親の期待値:115円
還元率:88%

[学び]

  • 辞書の使い方
  • round関数の使い方
  • printを用いる際のstr変換

・辞書の使い方

p_list = {"p_pin": 1 / 216, "p_666": 1 / 216, "p_555": 1 / 216, "p_444": 1 / 216, "p_333": 1 / 216, "p_222": 1 / 216, "p_456": 1 / 36, "p_6": 15 / 216, "p_5": 15 / 216, "p_4": 15 / 216, "p_3": 15 / 216, "p_2": 15 / 216, "p_1": 15 / 216, "p_123": 1 / 36, "p_0": 108 /216}

役をkeyに確率をvalueにすることで辞書の機能を用いました。実用的であったかは分からない、

・round関数

round(p1_pin * 100, 2)

確率を出力する際、小数点以下が鬱陶しかったのでround関数を用いることで見やすくできた。

・printを用いる際のstr変換

print("親の勝つ確率:" + str(round(sum_p1w * 100, 2)) + "%")

printで出力する際に数字と文字を一緒にprintすることができなかったのでstr変換を用いた。printの結果を分かりやすくしたかったので役立った。

[まとめ]

今回は、Pythonの学習を始めて初めての実践だったのですが結果を導くことができて嬉しかったです。結果について気になる方は別の記事で詳しく書いてありますのでそちらを読んでもらえればと思います。これからも継続して学習していきたいです。

コメント

タイトルとURLをコピーしました