2017年3月2日木曜日

FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その2

前回(FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】)からの続きです。

FC版ドラクエ1のレベル18にしてはりゅうおうに勝率50%とやけに高いなぁと思っていましたが、原因がわかりました。
if myMP >= 10:
behoimi = random.randint(85,100)
print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
view raw 03021 hosted with ❤ by GitHub


これが問題のコードです

HPが48以下のときにベホイミをかけるループですね

 if myMP >= 10:
 #MPが10以上ならベホイミをかけられるのでかけます

                    behoimi = random.randint(85,100)
                    print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
                    myHP += behoimi
                    myMP -= syouhiMP
                    if myHP >115:
                        myHP =115
#上から順に
#ベホイミ回復量85-100を 変数behoimi に代入
#文章
#自分のHPに behoimiを足す
#自分のMPをshouhiMP (10)を減らす
#HPが最大HPの115より大きくなってしまった場合、115に戻す


さて、ここから次の文章へのつなぎ部分が問題でした


  if myMP >= 10:
                    behoimi = random.randint(85,100)
                    print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
                    myHP += behoimi
                    myMP -= syouhiMP
                    if myHP >115:
                        myHP =115
                    else:
                        damage = random.randint(6,12)
                        print ("  りゅうおうに " + str(damage) + " のダメージ")
                        HP -= damage

悪さをしていたのはこの else以降の文章のインデントでした

このelse文は直前のHP部分の条件にかかっています。
したがって、ベホイミをかけてHPが最大HP(115)に届かなかった場合、さらにりゅうおうに追加攻撃できる状態でした。


それは強いですね、チートですね。

さて、書き直しますと

if myMP >= 10:
behoimi = random.randint(85,100)
print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
view raw 03022 hosted with ❤ by GitHub



見た目ほとんど変わりませんが、結果は大きく違います




さらに計算を早く回すために無駄な文章は結局削除し、勝率だけを求めるコードに書き換えました。

戦闘回数は10万回! 勝率は・・・・!?


import random
kati = 0
make = 0
step = 100000
for i in range(step):
myHP =115
myMP = 100
HP = 130
syouhiMP = 10
try:
while HP > 0:
if myHP >48:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
elif myHP >0:
if myMP >= 10:
behoimi = random.randint(85,100)
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
ryucommand = random.randint(0,1)
if ryucommand == 0:
mydamage = random.randint(24,48)
myHP -= mydamage
elif ryucommand == 1:
mydamage = random.randint(42,48)
myHP -= mydamage
if myHP < 0:
make +=1
raise Exception
except Exception:
pass
print (kati /step * 100)
print (make /step * 100)
view raw 03023 hosted with ❤ by GitHub



勝率:32.6%

だいぶ減りましたね、実際この条件ではこのぐらいだと思います。

実際のプレイではさらに

  • 後手を引く
  • 第一形態でHPを削られている
  • MPを消費してしまっている
などが原因でもうちょっと下がります

ちなみに第一形態でHPが90になった状態で第二形態と戦う場合
勝率16.1%になります。

HP85の場合は13.8%でした。

プログラムでは10万回の戦闘を5秒ぐらいで終わらせますが、実機でやったら1戦に数十分かかるので、精神的にこの確率よりも低くなると思います。





(5秒で10万回戦ってくれるりゅうおうさん)





0 件のコメント:

コメントを投稿