タスク: ダメージと防御ボーナスの計算式をCardWirthに合わせる

Issue #253 open
k4nagatsuki repo owner created an issue

Issue 244のコメントより。

部分的に引用します。

敵キャスト1体(Lv6、HP50、ラウンド毎+5回復、回避-9抵抗-10防御+7白適性、対属性[肉体/精神/魔力/炎弱点/冷気弱点])

プレイヤー側はリューン、キーレ等の技能をバランス良く持たせた6人PT(全員Lv10)。 戦闘終了の度にプレイヤーキャラを全快。 10回ほど自動戦闘を行う

この時、

CW1.50では大体 1~2ラウンドで決着がつき、CWPyでは 5~8ラウンドで決着が付く事が殆ど

となるようです(上記コメントに体力ゲージのスクリーンショットあり)。

また、次のような現象が発生しているようです。

テストに使用した召喚獣カードを防御+7から+10に変更し、防御カード (先の報告で影と表現しましたが、正確には適性最悪である暗い緑です) を選択させてみたら、防御+10もむなしく、ダメージが発生しました。見切りやカード交換、攻撃、渾身の一撃を使用させた場合はきちんとダメージを無効化しました。

これについては次の動作が正常です。

CW1.50では防御カードを選択してもすべてのダメージを無効化していました。

また防御ペナルティがある場合はどちらの場合でもダメージが発生するようです。

Comments (81)

  1. Liar_cw NA

    CW1.50の検証結果の報告です。画像を添付します。これはプレイヤーキャラクターが敵キャストを攻撃した時のダメージの発生の有無のみを集めたもので、与えたダメージ値についての情報はありません。

    無効化.png

  2. k4nagatsuki reporter

    検証ありがとうございます。

    とりあえず上半分だけ再現するテストシナリオを作ってみたのですが、確かに1.50だとそのように動きます。そしてCWPyの動作は一致しません。

    意外なのが、+10(本体)+10×2(召喚獣)-10(ペナルティ)という構成でダメージが発生しない事です。例えば+ボーナスを重ねていくにつれて効果が半減するというような式であれば、+10×2の結果は+15となり、ペナルティ-5まではダメージ無効が維持されるという事に説明がつきますが、+10×3-10で無効化が発生するということは説明がつきません。また、+10+9-1でダメージが発生するというのもまったくおかしな話ということになります。

    少なくとも現行の能力修正の計算式は近似に過ぎず、厳密には間違っているのは確かなようです。この実験結果に合う式を考え出す必要があります。

  3. k4nagatsuki reporter

    もしや+10効果だけが計算式と別個に処理されていて、-1~5で1個の+10効果が、-6以上で2個の+10効果が打ち消されているのでは?と考え、本体+10、召喚獣+10×2、召喚獣-1×2、防御修正-1、さらにアイテム+9×10の対象を作って実験してみたところ、ダメージを無効化しないことを確認しました。どうも計算式は合っていて、そこに前記の特別処理が絡んでいそうです。

    その方向で実装してみます。

  4. k4nagatsuki reporter

    直前に書いた実験にちょっとミスがあって訂正ですが、どうも+10効果が3つ重なると-10のカードを何枚持っていようがダメージ無効化効果は消えなくなるようです。2つまでなら推測したように動きます。

    いくつかのテストパターンを追加してシナリオも更新。今回のテスト版で1.50と結果が一致します。

  5. Liar_cw NA

    CardWirthPy 0.12.3x Build: 2015-08-09 23:15:06

    昨日のテスト版の情報で申し訳ありませんが、行動キャンセル時の挙動について1.50とPyで差異があるように感じました。 あの後、こちらでも検証をしてみようと新たに検証専用シナリオを作成、検証中に気がつきました。

    防御行動カード等が関わる以上、Issue #253 ダメージ計算式に影響するとして、こちらに書き込ませていただきます。

    行動キャンセルは召喚獣カード等の使用時イベントではなく、クーポンによる敵キャストの特定とラウンド毎条件のイベントを利用しました。 つまり、ラウンド開始時に行動キャンセルが発生します。

    行動キャンセル時の挙動:

    ( Py )見切りの効果は適用されない。

    (1.50)見切りの効果が適用されている。攻撃を回避したときに効果が発生していることを確認。

    (1.50)効果が発生してもカードは消費しない。

    (1.50)見切りに失敗して自力(回避+10、極端な例)で避けた場合は、見切りのエフェクトなし。

    (共通)行動キャンセルを受けた場合はカードの消費(変動)等は発生しない。

    ( Py )攻撃を受けた時:防御カード(戦闘行動)による補正はないと思われます。

    (1.50)攻撃を受けた時:防御カード(戦闘行動)による補正はあると思われます。

    ※技能やアイテムの使用時の補正は未調査です。

  6. k4nagatsuki reporter

    効果がありながらカードが消耗されないというのは不自然なので、これは1.50の行動キャンセルのバグと考えたほうがよさそうな気がします。対応するべきかどうかは少し考えさせてください。もちろん、この現象によってバランスに大きな影響の出るシナリオが存在する場合は対応する必要があります。


    さらにあれこれ試していて気がついたのですが、どうも+8以上のカード3枚で+10効果が発生するようです。+8×2と+7×8では発生せず。

    明日以降詳細に調べます……。

  7. 暗黒 騎士

    +10関係は色々面倒だとは思っていましたが、まさかこれほどとは…。 自分も少しやってみました。

    テスト条件:1.50で暴露状態・所有時ボーナスつきのアイテムを複数持った敵に絶対命中全属性レベル比3の武器カードで攻撃。
    
    所持ボーナスアイテムカードの適性値が915(明緑~白)
    防御+9二枚 →無効化。
    防御+8三枚 →無効化。
    防御+8二枚・防御+7一枚 →有効。防御カード(適正値6)など+1でも使用時防御ボーナスがあるカード選択で無効化。
    防御+7四枚 →無効化。
    防御+6五枚 →無効化。
    防御+5七枚 →無効化。
    防御+4九枚 →無効化。
    防御+3十枚・使用時防御+3召喚獣一枚 →無効化。
    防御+2十枚・使用時防御+2召喚獣七枚 →無効化。
    
    所持ボーナスアイテムカードの適性値が08(黒~暗緑)
    防御+9二枚 →有効。
    防御+8三枚 →有効。
    防御+8四枚 →有効。
    防御+8四枚、防御+6一枚 →有効。防御カードなど+1でも使用時防御ボーナスがあるカード選択で無効化。
    防御+8五枚 →無効化。
    

    どうも低補正アイテムでも適性値9以上で大量に持てば無敵になるようです。(+4未満は現実的ではないですが) 面倒なことに無敵判定にも所有時ボーナスの適性の影響があるようで、2段階なのは共通しているようです。(100%と70%ぐらい?)

    単体で+10のカードがなければ絶対に+10扱いにはならないという通念があったと思いますが、誤りだったようで少し驚いています。当初はHAND氏の回避・抵抗コラムの例を合わせて単純に「同一値のボーナスを重複持ちするごとに+1」というような法則があるのでは?という仮説を立てたのですが、+5以下から必要枚数が多くなってしまい、いまいち法則を掴めず。

  8. Liar_cw NA

    CW1.50の挙動についての報告です。

    どうやらアイテムカード(所有時能力値修正)は値がプラスだろうがマイナスだろうが適性の影響を受け、召喚獣カードは適性は影響しないようです。

    いずれも適性白のとき、召喚獣(+10x2)&アイテム(-6)の条件だとダメージが無効化され、 適性が黒のときはダメージが発生しました。 適性白、アイテム(+10x2)&召喚獣(-6)の条件でダメージが発生。適性黒でも同様にダメージが発生。

    以下、暗黒 騎士 様のデータについて、一部気になった点の検証の結果。

    アイテム所有+4x9(白)では無効化し、アイテム所有+4x9(黒)の場合はダメージが発生しました。

    召喚獣カード、適性最高・最低どちらの場合も、召喚獣+10x2-6でダメージが発生。

    次の画像は、防御値修正について召喚獣カードのみを使って調べてみた結果です。

    150召喚獣カードのみ.png

  9. k4nagatsuki reporter

    テストシナリオにダメージのばらつき具合の検証機能を追加。

    試してみたところだいたい合っているようです。とりあえずこれで+10問題に専念できます。

    が、+10問題も深入りするのは避けた方がいいかもしれません。あまり細かいところまで合わせた所で、それによってメリットを享けるシナリオがあるとは思えませんし、過去には1.20→1.28のように仕様が変わってしまった事もあります。

    同じにできればできるに越したことはないのですが、あまりこだわると追求にかけた時間と成果が釣り合わないことになりかねません。

    とりあえず今日のところは、アイテムカードに適性が影響するというところに対応します。検証していただきありがとうございます。

  10. k4nagatsuki reporter

    まとめられた表を見ると、どうも三角関数が出てきそうな感じの勾配で無敵化までの必要枚数が変化していますね。それを出す式をベースとして、アイテムについての適性ボーナスを加えると、答が見えてくるかもしれません。

    手札選択ルーチンで体力減少者への回復行動が優先される判断では、一定の値ごとにボーナス値が決まっていて、その値は計算では上手く出せなかったと記憶しています。それと同じで、+10の時は1枚、+9と+8は3枚、+7は4枚……と、無敵化までに必要な枚数が固定で決まっているという可能性もありますね。

  11. Liar_cw NA

    そうですね、たしかに今まで誰も気が付かなかったような変態的なこの問題。 こんなものを取り入れるシナリオは存在しないでしょうし、これからも出ないと思われますが、 可能性があるとすれば、プレイヤー側が操作キャラクター1体に過剰に『防具』を持たせた時だと思います。

    ですが、軽く検証しただけでも事実とそのショックで夢にまで出たり、体調を崩してしまったほどです。 私としても ここらが潮時だと思います。精神衛生上、これに類似する問題が起きたときにまた対処すべきかもしれません。

    なんというか、重箱の隅を箸で突き破るような事をしてしまい、申し訳なく思っています。余計な負担をかけてしまい、すみませんでした。

  12. k4nagatsuki reporter

    こちらこそすみませんでした。うっかり+8のアイテムを3枚持たせてテストしたばっかりにとんでもないパンドラの箱を開けてしまいました。

    とりあえずこの辺で保留して、実際に問題が起きた時か、突然答が分かった時か、あるいはいずれ気が向いた時にでも、もう少し仕様が合うように対応を進める事にします。

    どうぞお大事になさってください。

  13. 暗黒 騎士

    え!? お二方がそういう認識であれば仕方ないですね。 調査&更新お疲れ様でした。

    >三角関数

    自分もやってみて選択ボーナスと似た感じの印象を受けましたね。

    >過剰に『防具』を持たせた時

    カナンの鎧が+4なのでそのあたりに設定しているシナリオもあり、神仙型に9枚持たせれば一応正規プレイの範囲で無敵化を再現できることになりますね…確かに衝撃的です。

  14. k4nagatsuki reporter

    適性緑丸のアイテムカードで再度実験してみたところ、無効になるまでの値が次のようにカオスでしたので

    • 7+7+7+6
    • 8+8+8
    • 9+9+1

    昨日言ったようにとりあえず一旦保留にして 次の近似解を実装する事にします。

    • 適性緑丸と白丸で、無効化までに必要な防御ボーナス数は次の通り。
      • +1 → 24件(不可能)
      • +2 → 17枚
      • +3 → 11枚
      • +4 → 9枚
      • +5 → 7枚
      • +6 → 5枚
      • +7 → 4枚
      • +8 → 3枚
      • +9 → 3枚
    • 適性黒丸の場合は必要枚数が3倍(アイテムカードのみ)。
    • 適性暗丸の場合は必要枚数が1.25倍(アイテムカードのみ)。
    • +10以外を重ねて得られる無効効果は1回分のみ。

    • -1以下×1で1回、-6以下×1で2回分、無効効果を打ち消す。ただし無効効果が3つ重なった場合は打ち消されない。

    たぶんCWの内部にはシンプルな計算式があるのだと思います。が、無理に探るとSAN値がなくなりそうなので、(たぶんですが)私は今後手を出しません。

    もちろん、興味のある方が探ってみる事は止めません(むしろ歓迎)。もし解答を得られた方が現れ、答を教えていただけた場合、諸手を挙げて実装させていただきます。

  15. hand.onlooker

    テスト例を見てますと「倍率1%を切るかどうか」が無敵化するかどうかの境界に思えます:

    • 8+8+8 → 倍率 (0.2)^3 = 0.008

    • 9+9+1 → 倍率 (0.1)^2*0.9=0.009

    • 7+7+7+6 → 倍率 (0.3)^3*0.4 =0.0108

  16. k4nagatsuki reporter

    確かにそう見えます!

    ありがとうございます。アイテムは適性が絡むようなのでとりあえず措いて、召喚獣でその線で検証してみます。

  17. k4nagatsuki reporter

    だいたいのところそのような挙動なのですが、どうも途中で誤差が発生している気がします。

    添付したシナリオの中で次の境界例を検証していますが、1.~3.は想定通りに動いているものの、4.~6.は予想に反した無効効果が発生してしまっています。

    1.
    6+7+8+6 = 0.0096 無効
    6+7+8+5 = 0.012 有効
    2.
    5+8+9+1 = 0.009 無効
    5+8+9 = 0.01 有効
    3.
    3+3+9+8 = 0.0098 無効
    3+3+9+7 = 0.0147 有効
    4.
    3+2+1+9+8+1 = 0.009072 無効
    3+2+1+9+8 = 0.01008 無効?
    5.
    3+4+9+8 = 0.0084 無効
    3+4+9+7 = 0.0126 無効?
    6.
    7+7+7+1+1+1+1+1+1+4 = 0.008609... 無効
    7+7+7+1+1+1+1+1+1+1 = 0.012914... 無効?
  18. k4nagatsuki reporter

    HAND氏の指摘が近似解なので、pull request #996で実装しました。

    適性による変動をちょっと調べてみましたが、

    • 適性レベル4・3は100%
    • 適性レベル2は75%
    • 適性レベル1は50%

    くらいでだいたい式が成り立つようです(しかし依然誤差が出る)。

  19. hand.onlooker

    添付のシナリオをいじってみたところ、8+9+1+2+3 は有効になるようです。

    「処理はカードの末尾から行い、倍率を掛け合わせるたびに小数第3位以下を切り捨てる。最終的な倍率が0.00になれば無敵化する」

    と予想すると、これまでの実験結果とつじつまが合います。 以下はこれまでの実験結果について予想を適用したものです:

    • 6+7+8+6 … 0.40→0.08→0.02→0.00 無効
    • 6+7+8+5 … 0.50→0.10→0.03→0.01 有効
    • 5+8+9+1 … 0.90→0.09→0.01→0.00 無効
    • 5+8+9  … 0.10→0.02→0.01 有効
    • 3+3+9+8 … 0.20→0.02→0.01→0.00 無効
    • 3+3+9+7 … 0.30→0.03→0.02→0.01 有効
    • 3+2+1+9+8+1 … 0.90→0.18→0.01→0.00→0.00→0.00 無効
    • 3+2+1+9+8 … 0.20→0.02→0.01→0.00→0.00 無効
    • 8+9+1+2+3 … 0.70→0.56→0.50→0.05→0.01 有効

    ※実際 2+1+9+8 や 1+9+8+1 も無効化状態になる。

    • 3+4+9+8 … 0.20→0.02→0.00→0.00 無効
    • 3+4+9+7 … 0.30→0.03→0.01→0.00 無効
    • 7+7+7+1+1+1+1+1+1+4 … 0.60→0.54→0.48→0.43→0.38→0.34→0.30→0.09→0.02→0.00 無効
    • 7+7+7+1+1+1+1+1+1+1 … 0.90→0.80→0.72→0.64→0.57→0.51→0.45→0.13→0.03→0.00 無効

    ※実際 7+7+1+1+1+1+1+1+1 は有効

  20. k4nagatsuki reporter

    たぶん100倍にして整数計算しているんだろうと思って試してみたんですが全然合わないので諦めていました。確かに順序が影響します。下のコードで計算した結果がぴったり合うようです。すばらしい!

    def calc_bonus(seq):
        r = 100
        for val in reversed(seq):
            r *= 10
            r *= 10 - val
            r //= 100
        return r
    
    assert calc_bonus([6,7,8,6]) == 0
    assert calc_bonus([6,7,8,5]) <> 0
    assert calc_bonus([5,8,9,1]) == 0
    assert calc_bonus([5,8,9]) == 1
    assert calc_bonus([3,3,9,8]) == 0
    assert calc_bonus([3,3,9,7]) == 1
    assert calc_bonus([3,2,1,9,8,1]) == 0
    assert calc_bonus([3,2,1,9,8]) == 0
    assert calc_bonus([8,9,1,2,3]) == 1
    assert calc_bonus([3,4,9,8]) == 0
    assert calc_bonus([3,4,9,7]) == 0
    assert calc_bonus([7,7,7,1,1,1,1,1,1,4]) == 0
    assert calc_bonus([7,7,7,1,1,1,1,1,1,1]) == 0
    assert calc_bonus([7,7,7,1,1,1,1,1,1]) == 1
    
    print "All OK."
    

    どうやらほぼ答が出たようなので俄然やる気が出てきました。残る問題は以下ですが、今から調査してきます。

    • 適性による変化量の厳密な値(小数点以下は切り捨てられるのか?)
    • 召喚獣カード・アイテムカード・使用中カード(アイテム・特殊技能)・本体ボーナス・状態ボーナスはどういう順序で計算されるのか?
    • 使用中カードは適性に影響されるか?
    • ペナルティ時の無効効果打ち消しは適性に影響されるか?
  21. k4nagatsuki reporter

    適性による変化量の厳密な値(小数点以下は切り捨てられるのか?)

    • アイテムの所持ボーナスの場合は適性4,3=100%、適性2=80%、適性1=50%。端数切り捨て
    • 召喚獣カードのボーナスは適性が影響しない

    使用中カードは適性に影響されるか?

    • 特殊技能の使用ボーナスは適性4,3=120%、適性2,1=100%。端数切り捨て
    • アイテムカードの使用ボーナスは適性が影響しない

    召喚獣カード・アイテムカード・使用中カード(アイテム・特殊技能)・本体ボーナス・状態ボーナスはどういう順序で計算されるのか?

    1. 使用カード
    2. 召喚獣カード
    3. アイテムカード
    4. 状態・本体

    状態によるボーナスと本体の持つボーナスの順序だけが不明です。数列の最後の2つを入れ替えても結果が矛盾するパターンは、ランダムな数列を数百万件作っても見いだせなかったので、どちらでもよいかと思います(数学的な証明はきっと誰かがやってくれるに違いない)。

    ペナルティ時の無効効果打ち消しは適性に影響されるか?

    • アイテムの所持ペナルティの場合は適性4=80%、適性3=100%、適性2=120%、適性1=150%。端数切り捨て
    • アイテムカードの使用ペナルティは適性が影響しない
    • 特殊技能の使用ペナルティは適性が影響しない
    • 召喚獣カードのペナルティは適性が影響しない

    適性周りはなかなかカオスでしたが、これでほぼ解明できたと思います。他のIssueで報告されている問題を直してから実装に手を付けます。

    テストに使ったシナリオを添付しますが、手動で状態を変えながら検証したので自動的にはテストされません。

  22. k4nagatsuki reporter

    一つ漏れていました。防御カードの使用ボーナスは適性に影響されないようです。

  23. k4nagatsuki reporter

    pull request #1001

    これで知られている状況は全て合いました。まだ漏れのあるレアケースがあるかもしれませんが、大筋はこれまでの検証で判明しているので、個別に対応できるでしょう。

    Liarさんの問題提起、Liarさんと暗黒騎士さんの実験データ、HANDさんの指摘と検証のおかげで、無敵化するか・しないかという、場合によっては致命的になりうる問題を解決することが、どうやらできたようです。感謝します。ありがとうございました。

  24. k4nagatsuki reporter

    ペナルティはどうやら-1か-6を境に無敵効果を1つか2つ打ち消すという推測で合っているようなのですが、2段階目の打ち消し効果が発揮されるのは、適性が最大のアイテムで最大で-8、最悪適性で-4まで変動しました。従って、上にも書きましたが、次のようになるようです。

    • アイテムの所持ペナルティの場合は適性4=80%、適性3,2=100%、適性1=150%。端数切り捨て

    まあ計算結果ではなく固定値かもしれないのですが……。

    上の方には適性2で120%と書いていましたが実験ミスで間違いでした。アイテムの所持以外に関しては、こうした変動はないようです。

  25. k4nagatsuki reporter

    完璧だと……いいなぁ……。

    いや、本当にありがとうございました。HANDさんの最後のひと押しが無ければきっと年単位で諦めていたと思います。

  26. 暗黒 騎士

    現状、Pyにおいてボーナス値の計算式はINT型で切り捨てが発生していますが、無名し氏の検証結果ではCWでは「異なるボーナス枠」(アイテム所持ボーナスと使用時ボーナスなど)では9.0を超える防御ボーナスが得られるようです。

    これは合わせた方が良いのではないでしょうか?

    https://twitter.com/nameless_shi/status/1436377481741627392

  27. k4nagatsuki reporter

    ご報告ありがとうございます。

    テストシナリオを作ってみました。3,7とそれ以外とを見比べてみてほしいのですが、なぜかアイテム・スキルの使用ボーナスに限ってその他のボーナスと効果の出かたがまったく違うようです。
    合わせるのはいいのですが、どうも一筋縄ではいかないような感じがします。

  28. 暗黒 騎士

    テストシナリオ拝見させて頂きました。(最初戸惑いましたが比較しやすかったです。)

    自分の方での結果では以下になりました。

    1.50使用

    [7]アイテム所持+9x白適性100%、スキル使用時+9x白適性120%(ゲージ1割)
    [6]アイテム所持+9x黒適性50%、キャスト修正+8、状態ボーナス+7(ゲージ3割)
    [5]アイテム所持+9x黒適性50%、状態ボーナス+9(ゲージ6割)
    [4]アイテム所持+9x黒適性50%、キャスト修正+9(ゲージ6割)
    [3]アイテム所持+9x白適性100%、アイテム使用時+9x白適性100%(ゲージ1割)
    [2]アイテム所持+9x黒適性50%、召喚+9(ゲージ6割)
    [1]アイテム所持+9x黒適性50%x2枚(一撃死)
    ※キャスト修正、状態ボーナスは100%固定

    どうも100%以上で判定できているのは3と7だけのようなので上記の適性補正を失念されていると言うことなのかなと思ったのですが、
    以下に改変した結果、アイテム所持同士では少数切り捨てがある?という結果とも食い違うので適性まわりになにか見落としがあるのかもしれません。

    [1]'アイテム所持+9x白適性100%x2枚(ゲージ1割)
    [4]'アイテム所持+9x白適性100%、キャスト修正+9(ゲージ1割)

  29. k4nagatsuki reporter

    ああー、そうか! 適性がありましたね。完全に忘れていました。使用率を高めるために最大適性にしておいた結果効果が最大になっていたわけですね。

    たぶんいろいろコーナーケースがありそうなのでテストコードを作って色々実験した方がよさそうな気がしてきました。

  30. 暗黒 騎士

    全カードを白適性にして再度確認したところ[6]は無敵化、他はゲージ1割という結果になりました。

    ところでPyにおいてはどのテスト結果もゴリゴリに減っています。_get_enhance_implのvalue = int(b - a)のintを取り除くだけで概ね同じような結果になるようなのですが、使用ボーナスの[3][7]だけは依然としてゴリゴリに減ります。

    どこかで使用ボーナスだけ例外的な処理をしているのか?と大分悩んだのですが、結論だけいうと+10にしても減っているので、そもそも毎ラウンドイベントにおける効果コンテントでは使用ボーナスが適用されていない感じです。1.50では適用されているようです。

    ここら辺はたしか「使用前/使用済カード(手札に残るカード・残らないカード)」の検証でこのような実装になったと記憶していますが……なにか注意しなければならないケースはあったでしょうか。

  31. k4nagatsuki reporter

    pull request #291

    とりあえず種類別に計算される挙動はだいたい合わせられたと思うんですが……ただ、最大値ボーナスとその相殺がうまく再現できません。+10と-10の所持ボーナスの両方をアイテムカードで与えた場合と、どちらか片方を別の方法で与えた場合とでは結果が異なり、後者がまるで合いません。

    とりあえず疲れるまで追求してみたのですが、疲れただけに終わりました。ここを合わせてもあまりいい事は無さそうなので放置したい気持ちになっています。


    使用ボーナスが行動キャンセルで消滅する件ですが、どうも使用済カードが消滅しても能力修正が残るのと同じ事が行動キャンセルでも起きていそうです。とりあえずそういうふうにしてみました。

  32. k4nagatsuki reporter

    pull request #292

    -10が複数あったり-10と-5があったりしたような場合の挙動が合うようになりました。相殺がある場合の挙動はさっぱり合いません。

  33. k4nagatsuki reporter

    今の状態だと-10がある時に他のプラスボーナスが全部打ち消されてしまいますね。うーん、しかし正しい答が分からない……。

  34. 暗黒 騎士

    修正・検証お疲れ様です。上のシナリオを改変させてもらい、一先ず白適性所持アイテム+10-10で比較してみましたが、どうも-10の場合、適性補正は無視されるのかもしれないということがわかりました。
    長月さんのテストケースにこれが当てはまっているかわかりませんが、参考になれば幸いです。

    [1]※1所持アイテム白適性(80%)+10-10      1.50 ゲージ半分 Py ゲージ6割
    [2]※1修正0                   1.50 ゲージ半分 Py ゲージ半分
    [3]※2所持アイテム白適性(80%)-10        1.50 ゲージ2割 Py ゲージ6割
    [4]※1所持アイテム白適性(80%)+5-5       1.50 ゲージ5割強 Py ゲージ5割強
    ※1 HPが削れすぎるためレベル比5で測定 ※2 レベル比2で測定

    [1-2]CWでは能力修正0と白適性所持アイテム+10-10はほぼ同等のダメージになっていますが、Pyだと後者の場合にボーナスが勝っています。printしたところPyでは10-8で防御ボーナス2になっていました。
    白適性なのでペナルティが80%として引かれたということですね。一方1.50ではプラマイゼロで防御修正0として見なされたようです。

    [3]-10単体での比較で結果に差が付いているので、相殺時のみおかしくなるという線が消えました。

    [4]+5では1.50でも適性補正がつき、ほぼ同等の結果になりました。

  35. k4nagatsuki reporter

    pull request #293

    適性補正の事をヒントに「+10は適性が関係ないが-10も同じように動くのでは?」と推測してそのようにしてみたところ、実際にそういう傾向のようでした。

    動かして比べてみると微妙な差が出ますが、方向性としては一致した結果が出ます。

    ただ、+9を3枚重ねると+10の効果が出ますが、-9の場合は3枚では微妙に届かないようです。プラスとマイナスで式が違うか、丸める方向などの問題があるのかもしれません。

    さしあたり、上記Pull Requestの結果は許容範囲内くらいには合っているのではないかと思います。

  36. 暗黒 騎士

    上の方(6年前)で長月さんが発見された「全枠で防御+10が合計3枚あれば-10をいくら積んでも通らなくなる現象」(仮に「完全無敵」と呼びます)、+10が単純に3枚ある場合は順番がばらばらでも無効化される感じですが、+10x2枚+繰上がり無敵化の時、手札の位置によって完全無敵になる場合とならない場合があるようです。

    [1]+10x3枚-大量のペナルティ 1.50 完全無敵 Py 完全無敵
    [2]アイテム(+10+10+9+9+9)+召喚獣(-10-10)+能力変化-10 1.50 完全無敵 Py 完全無敵
    [3]アイテム(+9+9+9+10+10)+召喚獣(-10-10)+能力変化-10 1.50 ダメージ発生 Py 完全無敵
    [4]アイテム(+10+9+10+9+9)+召喚獣(-10-10)+能力変化-10 1.50 ダメージ発生 Py 完全無敵
    [5]アイテム(+9+9+9+9+9+9+9+9+9+9)+召喚獣(-10-10)+能力変化-10 1.50 ダメージ発生 Py ダメージ発生
    [6]アイテム(-10-10)+召喚獣(+10+10+9+9+9)+能力変化-10 1.50 完全無敵 Py 完全無敵
    [7]アイテム(-10-10)+召喚獣(+9+9+9+10+10)+能力変化-10 1.50 ダメージ発生 Py 完全無敵
    ※PyはBuild: 2021-09-12 21:41:01で確認

  37. 暗黒 騎士

    その他、ヒントになるかもしれないので、バイナリ改変で11以上の値を入れてわかったっぽいことを列挙しておきます:

    • 「完全無敵」になると防御ペナルティ-1~10はどれだけ積まれても受け付けないが、-11以上のペナルティが一つでも付けばダメージが通る。
    • 「完全無敵」は11や11以上を合計3枚積んでも発生しない(通常の無敵は発生するが-9ペナルティで貫通可能)。「10」か「繰上がりで10相当」のみがカウントされている?
    • 11以上は10と異なり、適性の影響があるっぽい。
    • 行動力は上下するだけダメージに影響するが、防御ペナルティは恐らく-11以上でも「4倍」で固定(4倍ダメージが無敵化に対応する特殊効果?)

  38. k4nagatsuki reporter

    無敵の発生有無を計算するアルゴリズムのどこかで一定桁数以下が切り捨てられてるとかですかね?

    +10だけ特別というのはまあいいとして、-11以下も特別扱いされるとなると、やはりプラスとマイナスで微妙にアルゴリズムが違うんでしょうね。


    防御以外はどうなのかな、と思って抵抗修正を調べてみましたが、こちらは特に種類別に計算が行われたりといった事は無いようでした。

  39. 暗黒 騎士

    使用時ボーナスが絡んだパターンを追試しました:
    スキル使用時+10、アイテム所持+10+9+9+9、召喚獣-10-10、状態変化-10 完全無敵
    スキル使用時+10、アイテム所持+9+10+9+9、召喚獣-10-10、状態変化-10 ダメージ発生
    スキル使用時+10、アイテム所持-10-10、召喚獣+10+9+9+9、状態変化-10 完全無敵
    スキル使用時+9、アイテム所持-10-10、召喚獣+10+10+9+9+9、状態変化-10 完全無敵
    スキル使用時+9、アイテム所持-10-10、召喚獣+10+10+9+9、状態変化-10 ダメージ発生
    スキル使用時+10、アイテム所持-10-10、召喚獣+9+9+9+10、状態変化-10 ダメージ発生
    アイテム使用時+10、アイテム所持-10-10、召喚獣+10+10+9+9、状態変化-10 完全無敵
    アイテム使用時+10、アイテム所持-10-10、召喚獣+9+10+9+9、状態変化-10 ダメージ発生
    アイテム所持+10+9+9+9、召喚獣-10-10、状態変化-10、キャスト修正+10 ダメージ発生
    アイテム所持+10+10+9+9+9、召喚獣-10-10、状態変化-10、キャスト修正-10 完全無敵
    アイテム所持+10+10+9+9、召喚獣-10-10、状態変化-10、キャスト修正+9 完全無敵
    スキル使用時+10、アイテム所持+9+9+9、召喚獣-10-10、状態変化-10、キャスト修正+10 ダメージ発生
    スキル使用時+10、アイテム所持+10、召喚獣-10-10、状態変化-10、キャスト修正+10 完全無敵※10x3枚パターン
    アイテム所持+10+10-10+9、召喚獣-10-10、状態変化+9、キャスト修正+9 完全無敵
    アイテム所持+10+10-10、召喚獣-10-10+9、状態変化+9、キャスト修正+9 ダメージ発生
    アイテム所持+10+10-10、召喚獣+9-10-10、状態変化+9、キャスト修正+9 ダメージ発生
    アイテム所持+10+10、召喚獣+9-10-10-10、状態変化+9、キャスト修正+9 ダメージ発生
    アイテム所持-10-10-10、召喚獣+10+10+9、状態変化+9、キャスト修正+9 完全無敵
    アイテム所持-10-10-10、召喚獣-10+10+10+9、状態変化+9、キャスト修正+9 完全無敵
    アイテム所持-10-10-10、召喚獣-10+10+9+10、状態変化+9、キャスト修正+9 ダメージ発生
    アイテム所持-10-10-10、召喚獣-10+10+10+9+9、状態変化+9、キャスト修正-1 完全無敵
    アイテム所持-10-10-10+10、召喚獣+10+9+9、状態変化+9、キャスト修正-1 ダメージ発生

    アイテム所持+10+10+9、召喚獣+9+9、状態変化+0、キャスト修正-10 ダメージ発生
    アイテム所持+10+10+9+9、召喚獣+9+9、状態変化+0、キャスト修正-10 ダメージ発生
    アイテム所持+10+10+9+9、召喚獣+9+9、状態変化+1、キャスト修正-10 完全無敵
    アイテム所持+10+10+9+9、召喚獣+9+9、状態変化-10、キャスト修正+1 完全無敵

    多分簡潔な切り捨ての計算式があると思うのですが、確実に起こっていることをまとめると以下になります。

    • 条件1:+10x2枚+繰上がりパターンで完全無敵が発生するには、 「アイテムか召喚獣枠のボーナスだけを見て、1番先頭が連続して+10×2枚である」もしくは「一番先頭が+10であり、使用時ボーナスも+10である」必要がある。その他の組み合わせで+10が2枚あっても完全無敵は発生しない(ペナルティを差し引いたあとの無敵化は発生する)。3枚では順序に関係なく発生する。
    • 条件2:+10に連続して「同枠での+10以外のボーナス、状態変化、キャスト修正」で繰上がり無敵に達する必要がある(アイテム所持で+10x2、召喚獣で+9+9+1はNG)。少なくとも+10以外の使用時ボーナス、アイテムと召喚獣は互い切り捨てが発生している?

    流れとしては+10が連続していれば使用時ボーナス→(アイテム所持合算)・(召喚獣所持合算)までは切り捨てが発生せず、アイテム所持か召喚獣のどちらかが繰上がり完全無敵条件を満たしそうな場合は片方を無視し、キャスト修正・状態変化のボーナスをみるみたいな感じだと予想しています。

  40. k4nagatsuki reporter

    これはシンプルな原因があると思うのですが(そんなところに複雑な仕様を入れる理由がない)、追及するのは相当面倒そうですね……。

    調査に費やす労力と得られる成果を秤にかけるとモチベーションが上がらないというのが正直なところです。

  41. 暗黒 騎士

    上記の結果からの推論に少し抜けがありました。

    使用時ボーナス+10、アイテム所持ボーナス+9+10+9+9+9、召喚獣-10-10-10-10-10 状態変化-10で完全無敵が発生します。つまり、2枚連続配置は必要条件ではありません。そこで、間に+10が入った時点で都度端数0にリセットされているのではないか?と仮説を立て、一旦無敵化から離れてダメージを見ていたのですが、使用時+9、所持+9+10+9+9+9、召喚-10-10、状態変化-10の結果は単純に+5ボーナスを持たせた場合と大体同じダメージになります。

    どうも「+10」が2枚以上重なるとき、どんなにペナルティ値が付いても打ち消されない、いわば「固定+5ボーナス」が付くっぽいです。
    「+10x3枚による完全無敵」は、これが単純に合算された結果、+10に到達して「通常の最終ボーナス+10-通常の最終ペナルティ10の和+(固定ボーナス+5*2)=10」になっているという風に考えています。ペナルティ-11でダメージが通るのも(+10-11)+10=9で説明が付きます。

  42. 暗黒 騎士

    Rebootでは不正値を丸めているので実装には影響しないと思いますが、この固定ボーナスは内部的には10を超えて加算されているようです。4枚重ねれば15相当になり、-11を持ってしてもダメージが通りません。

    理論上、正規に積める防御ボーナスは使用時/アイテム所有/召喚獣所有/キャスト修正/状態変化なので23-1x5=110まで上げられることになります。使用ボーナス10+所持20枚+キャスト修正10(状態変化はペナルティで使うので合計105相当)のキャストに対し、防御力変化モーションでペナルティ-100してから必中ダメージを与えましたが、通らず。-255した場合では通るので、上記想定で無制限に加算されていくということでほぼ間違いなさそうです。

  43. 暗黒 騎士

    リリースの方のコメントを拝見しましたが、上記の固定+5ボーナスは実装されないということでいいんでしょうか?

    現状のPy(Build: 2021-09-25 12:54:08)だと使用時+10アイテム所持+10召喚獣-10、状態変化-10で恐らく9.9割カットが発生していますが、
    使用時+10アイテム所持+10召喚獣-10-10-10状態変化-10では防御力が0かマイナスになってます。

    この結果は1.50ではどちらも固定ボーナスによって+5相当になります。(+10-10+5)


    自分の結論としては、

    • 計算式は「通常ボーナス-通常ペナルティ+固定ボーナス」
    • 「+10」が2枚以上カウントされるごとに固定ボーナスに+5
    • ペナルティ側には固定ペナルティに相当するものはない
    • 最後に1度だけ「掛け合わされた結果+10効果が発生するか」という処理があり、この結果得られた「+10効果」でも上記の固定ボーナスにカウントされるが、これは「式上で最後の+10が来た後」の値で計算されている(+10をカウントする時に変数が都度0になっていて、+10カウントが1以上で計算後の変数<10の時、10を入れ直しているか、その時点での最大値(通常は+10)でINTされているか)

    ということですが、上の検証では召喚獣とアイテム所持の計算順が曖昧だったので追試しました。

    U+10 I+10 B+9+9+9-10 S-10 無効
    U+10 I+9+9+9 B+10-10 S-10 ダメージ発生
    U+10 I+9+9 B+10-10 C+9 S-10 無効
    U+10 I+10 B-10+9+9+9 C+9 S-10 ダメージ発生

    U=使用時、I=アイテム所持、B=召喚獣、S=状態変化、C=キャスト修正

    なので処理順は上記の長月さんの検証通りと思われます。

    1. 使用カード
    2. 召喚獣カード
    3. アイテムカード
    4. 状態・本体

  44. k4nagatsuki reporter

    検証された内容の細部まで確認できていないのですが、アルゴリズムとしては結論が出ているという事でいいのでしょうか?

    今現在検証とテストまで含めて実装する余裕が無いので、可能であればPull Requestを出していただけるとありがたいです。不可能であれば余裕ができた時に私が対応します。

  45. 暗黒 騎士

    固定ボーナスについては不正値も含めて帳尻が合っているので確信していますが、反応から長月さんの検証された相殺の食い違いをすべて説明できるロジックではないのかな?という印象だったので。確認できていないということであれば了解です。
    念のため、シェアできる部分はそうした方がいいだろうというスタンスなので、無理して対応して頂く必要はありません。

    PullRequestで「長月さん側の手間が軽減される」のならいいのですが、実際の所は逆で、お忙しい中わざわざ長月さんに負荷の多い手続きを踏むのは気が進みません。とか言ってると丸投げの逃げ口上にも映りそうなので、不要かとは思いますが、手元で変更した箇所を列挙します。

    • 上記の通り、式に直接変数を追加するため_get_enhance_impl内の変数max10counterは必要ないので、関連の処理を全て削除
    • 返り値のmax10を比較ではなく変数をそのまま返す
    • add_pvalで値が10の時、リストを空にする:del pvals[:]としたがPython3ならclearも使える?
    • _get_enhance_impl_iの式

      if max10 > 1: fixed = (max10-1) * 5 value = (b - a) + fixed else: value = (b - a)

    get_enhance_defでは現状の実装だとi→f(intからfloat?)の順に処理、iで10か-10ならreturn、それ以外のときfで計算するという二段階フロー?のようなのでmax10=2の結果である5でもreturnするかimpl_iの返り値でもmax10を受け取って判定が必要になりますが、impl_iは抵抗や回避処理でも使い回しているのでスマートな直し方が思いつきませんでした。

  46. k4nagatsuki reporter

    ありがとうございます。

    私の反応については、検証内容を正確に理解するための気力と時間が確保できていないという状況から出ているものなので、当てにならないものと思っていただいた方がいいかと思います。

    Pull Requestで手間が軽減されないというのはよく分かりません。調査・検証・実装・テスト・再検証とコードレビューでは通常後者の方が楽なのですが(でないと分業が成り立たないので)。

    問題となるケースをリストアップしたり(それはコード内にコメントで書いた方がいいかもしれませんが)、テストシナリオなどもつけていただけるとレビューで確認しやすくなりますが、一応手もとにあるシナリオでもなんとかできるとは思っています。

  47. 暗黒 騎士

    うーん?上述の通り数行・数カ所で済むコーディングは自分でやった方が早いはずです。そして、コードレビューする側にも検証・コードの理解・テストが必要です。でなければ間違いを指摘できないので。

    直裁に言えば、長月さんがそういうお気持ち表明をされる時っていうのは経験上かなり参っているときで、コメントはスルー出来ても(それも余裕があればしたくはないのでしょうが)、PullRequestがあればやる気がないことでも優先度を繰り上げて無理してでも対応に努めようとしますよね?
    「ありがたい」と言っているのはおかしい(自滅)ですし、おかしな対応をせざるをえないくらいお忙しいのでしょうから、追い打ちをかけるようなことはこちらとしてもしたくありません。健康を優先して下さい。

  48. k4nagatsuki reporter

    お気遣いいただけるのはありがたいです。

    どこから説明すればいいのかわからないので箇条書きにしてみます。

    1. この件は、正しい答が不明な時点では近似的な実装をするしかない問題でしたが、答が明らかである事が示された以上、β4リリース前に実装を済ませるべき課題になりました。対応が必要です。できれば早く済ませたい案件です。

      • そういえばこれが残件になっているのでβリリースを延期しているのですが#1045で告知してませんでした。あとで書いておきます。
    2. Pull Requestにすぐに対応しなければならないというルールは無いです。Issueと同じ程度には対応します。

    3. 自然言語で記された変更内容を書き写すと大抵事故が起きます。

      • 例えば#1047では私が安易にコード片を示した結果、書き写す過程で誤りが入り込み、いったんマージした後で修正する事になりました。
      • 変更元のリビジョンが明確になっていなければなりません。例えば上の方で示された「_get_enhance_implのvalue = int(b - a)のintを取り除く」という変更を手元で加えたところダメージ計算がCW 1.50と全く合わなくなりました。おそらくなにか前提が違ったのでしょう。VCSを使えばそうした漏れ・抜けは発生しません。
    4. この件で最も時間と手間がかかるのは比較検証とテストで、手動でコードを移植した場合はコード提示側の検証とテストは一切当てにできませんので(理由は3.)、全部やり直す必要があります。

    どうしてもPull Requestが出せないようであれば、せめてdiffを出していただけるとありがたいです。多少手間はかかりますがdiffを元にパッチ当てをすれば上記問題のいくつかは発生しなくなります。

    もちろんPull Requestで非常に多くの誤りが含まれるコードが送られてくるとか根本的に間違っているコードが送られてくるとかすれば、別の、事によっては莫大な手間暇が発生しますが、今回のはそういうタイプの問題ではないと認識しています。

  49. 暗黒 騎士

    正直見立ては変わりませんが、上記やりとりで既にコストを膨大に浪費させてしまっている気がして本末転倒なのでPRしてみます。

    また、検証用に上記の再改変したテストシナリオを付属します。

    以下は双方での結果です。

    1.50でのゲージの割合(デフォルト素材基準)

    [1]3.5 [2]2.5 [3]3.5以上 [4]4.5 [5]完全無敵(状態変化-255以上でも突破不能) [6]戦闘不能 [7]無敵(-110以上でないと突破不可)

    PyR+ClassicS Build: 2021-09-25

    [1]x4.9 [2]x戦闘不能 [3]o [4]x 4.9 [5]不正値を通さないので結果的に合致[6]o [7]5と同じ理由で不合致

    PRでは[1][2]を([7]も固定ボーナス側においては)修正します。小数点切り捨ての計算順が原因と思われる[4]と後述の-10の割り込み処理が原因と思われる[5]についてはノータッチです。

    [5]は10x3-10x2で通常ボーナス10通常ペナルティ10固定ボーナス10=+10にすぎないはずですが、なんと状態変化で-4000してもダメージが通りません。キャスト修正-9に調節した途端-11で通ります。つまりキャスト修正-10の時、状態変化の値は無視か上書きされている可能性があります。

    +10同様の上書きであると仮定すると曖昧だった「状態変化とキャスト修正の順番」は「キャスト修正が一番最後」ということになります。

    ⇒キャスト修正であえて-10を設定、所持ボーナスで+10を2枚持たせることで「不正値も含めたデバフが通じない永続ボーナス+5持ちのボス」が作れます。

  50. 暗黒 騎士

    こちらこそ対応ありがとうございました。

    残るは[4][5]の件ですが、[4]は+9+9-1ですがこれは1.50では+9相当のダメージになっているようです。つまり小数点は考慮されているはず(9-1ではなく9.9-1.0の結果8.9か9になっている)で、Pyでは9.9か9.8相当になっています。print文で処理をみたところ、「-1+9+9」という修正値のリストは渡されているっぽいのでcalc_defensedvalueの「for文でfloatにした修正値のリストを順次適用していく」という処理が原因かもしれません。

    [5]はPRの方で触れたadd_pvalでマイナス方向の値を扱うのであれば-10でも+10と同じようにリストを初期化すればよさそうです。

  51. k4nagatsuki reporter

    [5]は10x3-10x2で通常ボーナス10通常ペナルティ10固定ボーナス10=+10にすぎないはずですが、なんと状態変化で-4000してもダメージが通りません。キャスト修正-9に調節した途端-11で通ります。つまりキャスト修正-10の時、状態変化の値は無視か上書きされている可能性があります。

    これがCW 1.50でも再現できないんですが、キャストの防御修正を-9に変更する事の他になにか条件があるんでしょうか?

  52. 暗黒 騎士

    -11で通るというのは能力変化モーションで不正値ペナルティ-11を与えるという意味です(固定ボーナスで10なので、キャスト修正を-9にしただけであれば10-9+10=+11でダメージが通りません)が、検証シナリオ内には含まれていません。

    意味が通じていて-11するカードを持ち込んでいる場合、自分の検証に使ってるカードが間違っている可能性がありますが……お見せできる内容ではないんですが、毎回改造するのも面倒くさくなって作った検証用改変カード群です。剣シリーズは必中で-9~-255までのペナルティと直接値ダメージを与えます。付帯能力は行動力を255します。

    https://bitbucket.org/akkw/cwpyreboot_pr/downloads/Power.zip

  53. k4nagatsuki reporter

    pull request #300

    ありがとうございます。とりあえずpvals周りは修正しましたが、やはりマイナスとプラスを組み合わせると合わないケースが残りますね。

    とりあえず現時点で分かっている限りの近似にはなっていると思うので、これでβ4をリリースするべきかもしれません。

  54. 暗黒 騎士

    あれ?すいません、意図が伝わっていない気がしますので確認させて下さい。

    [4]ダメージを実際に処理するeffectmotionの「calc_defensedvalueのfor文が正常に機能していない」(9+9-1が9.9-1.0になっていない)
    [5]「-10が入るとそれ以前のペナルティは上書きされる」「現状のPyでは計算順がキャスト修正→能力修正となっているが、能力修正→キャスト修正となっている可能性がある」

    ということです。自分としては[5]と[4]では[4]の影響度の方が遙かに高いと思っています。

    適性補正の事をヒントに「+10は適性が関係ないが-10も同じように動くのでは?」と推測してそのようにしてみたところ、実際にそういう傾向のようでした。動かして比べてみると微妙な差が出ますが、方向性としては一致した結果が出ます。

    ということだったので、[5]は上で長月さんが実装された「min10をカウントする処理」がどこかで使われている場合に計算がズレることになる(たとえば-9-10-9-9-9の場合にリストを消さないとmin10は2となってしまいます)のですが、現状、min10のカウント数はどこでも使用されていないので、直してもあまり意味がない気がします。なので「マイナス方向のpvalsはどういう意図で実装され、どうすべきなんでしょうか?(min10をカウントするのであれば[5]もついでに直した方が良いかも)」という感じの確認になりました。


    [4]の修正ですが、effectmotionのcalc_defensedvalueを単一の防御値を受け取るだけの旧実装に戻し、非常に拙い実装で恥ずかしいのですが、以下のようにしたところ概ね正しい出力が得られたように見えます。(Python2/3ではfloat計算の仕様変更があるようなのでそのままは適用できないかもしれません)

    #Python3ではreduceが移動されたためfunctoolsもインポートする
    import operator
    
    def get_enhance_def(self):
        """
        """
        seq = []
        seq2 = []
        ivalue, max10 = self._get_enhance_impl_i("defense", self.enhance_def, 2)
        if max10 > 0:
            return ivalue
        if 10 <= ivalue or ivalue <= -10:
            return ivalue
    
        for btype in (Character._BTYPE_SKILL, Character._BTYPE_ITEM_USE, Character._BTYPE_ITEM, Character._BTYPE_BEAST,
            Character._BTYPE_ACTION, Character._BTYPE_CAST, Character._BTYPE_STATUS):
            value = self._get_enhance_impl_f("defense", self.enhance_def, 2, btype=btype)
            if value > 0:
                seq.append(10-value)
            elif value < 0:
                seq2.append(10-value)
        bonus = 0
        penalty = 0
        n = len(seq)
        n2 = len(seq2)
        if n > 0:
            seq = reduce(operator.mul, seq, 1)
            bonus = (10 ** n - seq) / 10.0 ** (n-1)
        if n2 > 0:
            seq2 = reduce(operator.mul, seq2, 1)
            penalty = (10 ** n2 - seq2) / 10.0 ** (n2-1)
        fvalue = bonus + penalty
        print fvalue
        return fvalue
    

  55. k4nagatsuki reporter

    pull request #301

    要は-10の特別扱いの考えかたが違っていたのではないかという事ですかね。

    大方合うようになりましたが、今度は+7,+8,+9の組み合わせがCW 1.50と合わないようです。こちらではボーナス値9.64になるのですが、1.50ではもう少し高い様子です。

  56. 暗黒 騎士

    うーん、自分としては、「適性を無視する」のと「それ以前の補正値を上書きしている」ことから-10側も特別扱いしているのはほぼ間違いなさそうなので長月さん側がmin10を利用している部分をなにか見つけているのであれば詳細を理解したい感じでした。

    +7,+8,+9の組み合わせは自分の方だと1.50Pyともにmax10判定の方で無敵(10)になってしまうようです。
    ちょっと考えたのですが、「DamageTest_Def9」の[6]のことでしょうか。たしかに削れているようです。
    ぱっと見、1.50ではアイテム所持+9の黒適性50%が切り捨てられずに4.5となっているか、切り上げが起こってる感じでしょうか。

    Item+9 50%とC+4を作って比較しましたが、単体ならやはり4.0に切り捨てられているようです。自分の方ではaddvalアイテム所持適性処理部分のINTを取るとボーナス値9.7になり、丁度よくなりましたが、他のケースでの副作用が気になるところです。

  57. k4nagatsuki reporter

    pvalsにはマイナス値が入らないのでmin10は実際に機能していなかったはずで、またダメージ計算へ適用される数値が統合されて一件になったので-10が特別扱いされているように見えていた問題は解決しているのではないか、と解釈しています。

    ちょっと考えたのですが、「DamageTest_Def9」の[6]のことでしょうか。たしかに削れているようです。

    すみません、それの事です。防御関係だけ実数計算になっているという可能性は無くも無さそうですね。

  58. 暗黒 騎士

    int抜きで概ねあったので満足していたのですが、まだ穴がありました。 不味いのが[2]です。

    [1]アイテム所持+9+9=+9.9 ※Pyでは9.0
    [2]アイテム所持+9*+1黒適性(+0.5想定)+召喚獣+9=無敵 ※Pyでは9.91
    [3]使用+9 アイテム所持-1黒適性(-1.2想定) = 8
    [4]召喚獣+9+9=+9.9 ※Pyでは9.0
    [5]状態+9 アイテム所持-9黒適性=0
    [6]キャスト修正+9 状態+8 アイテム所持+1 =9.88
    [7]スキル+5(白) アイテム所持-5(黒)=0
    

    [1][4]は上記の通り無名しさんの検証とは食い違うのですが、同枠でもやはり9.9になっているようです。

    [2][3]はつまり、1は黒適性で0.5もしくは0になるはずですが1になっています。最低1/-1保証なのか切り上げなのか微妙なところですが、自分の直感としては召喚獣の使用回数の適性補正の例からして最低1保証かと思ってます。

    [5]まず「黒適性ペナルティ」は上の長月さんの検証によれば150%となるのですが、ソース上は120%となっていました。1.50での結果は0相当になっているのでどちらとも少々合いません。

    [7]9だと「10に繰り上がれるかルール」があって可能性を絞れないので5で実験しました。0、120%で合っているようです。すなわち[5]は9に丸められています。


    自分の方の実装です。

         def _get_enhance_impl_f
    ~~~~~~~~~~~~~~
                return cw.util.numwrap(value, -10.0, 9.9)#もしくは値をそのまま返す
    
         def addval
    ~~~~~~~~~~~~~~
                        if -10 < val < 0:
                            if 3 <= level:
                                val = (val * 80 / 100.0)
                            elif level <= 0:
                                val = (val * 120 / 100.0)
                            val = cw.util.numwrap(val, -9.0, -1.0)
                        elif 0 < val < 10:
                            if level <= 0:
                                val = (val * 50 / 100.0)
                            elif level <= 1:
                                val = (val * 80 / 100.0)
                            val = cw.util.numwrap(val, 1.0, 9.0)
                            # ボーナスは単体の+10がない限り最大で+9になる
    

  59. k4nagatsuki reporter

    検証に使える時間が蒸発してしまったので上記のコードだけ移植してみたのですが、上記したボーナス値9.64のところの計算が依然合わないようです。他のところも変更されているという事でしょうか?

  60. 暗黒 騎士

    変更していると言えばしています(不正値に対応するためラップ処理をコメントアウトするなど)が、出力に関係ある部分はそこだけという認識です。Python2と3では「/」だけでも計算結果が食い違うようなのでややこしいですね……。自分の方では以下のコードで「DamageTest_Def9」の[6]が1.50の結果(残りゲージ3.5)と近似した結果がでています。

    https://bitbucket.org/akkw/cardwirthpy-lite/src/master/cw/effectmotion.py#lines-692

    https://bitbucket.org/akkw/cardwirthpy-lite/src/master/cw/character.py#lines-1548

  61. k4nagatsuki reporter

    式をすべてfloatにしてもボーナスの計算結果は9.67になって対象の生命点は3.2~3.3ゲージくらいしか残らないですね。時間ができた時にそのままの移植を試みてみます。

  62. 暗黒 騎士

    うーむ、こちらもprint bonus + penaltyが9.67なのは一緒です。ということは以下で違いがでているということですかね?
    Python2でのreturn max(1, value * int(100 - enhance_def * 10) / 100)

    Python3でのreturn int(max(1, (value * (100 - enhance_def * 10)) // 100))

    あとは#747(直接値5以上で理論上の最大ダメージが発生していない)で返答がなかったので当面触れたくない感じかと思ってこちらでは-1を取り除いていますが、減っているなら関係なさそうです。

  63. k4nagatsuki reporter

    こちらでは最終的なダメージは27~34になっているようですがそちらでは異なる値になっていますか?

    過去の#747の件は過去のPull Requestの情報が消滅していて確認できませんが、このIssueで扱っている問題への対応なので-1を消してしまっても問題ない感じでしょうか。

  64. 暗黒 騎士

    damage_motion側のprint valueによる目視ですが24~31になっているようです。
    というかすいません、ビルドしたバージョンで試した方が話が早いかもですね(想定しているゲージの割合の表現方法が異なっているかもしれないし)。
    https://bitbucket.org/akkw/cardwirthpy-lite/downloads/CardWirthPyLite_t.zip
    そもそもintを入れている位置が違うので結果が食い違っているのは当然な気がしてきました。

    日付からすると自分はかれこれ2年?-1を取り除いた環境でテストプレイ/ビルドしていますが、自分のフォークは利用者が少ないのでなんとも言えません。当時はCWシナリオにおいて「理論最大ダメージが出ないと永久に止まらないループ処理」は(報告者の方が実際に作られたように)生まれうるが、実最大ダメージが1大きくなって停止する処理はあまり考えられないからとりあえず取っておけば良いやぐらいの勘定だった気がします。

  65. 暗黒 騎士

    (念のため、ここのところお忙しいようですので反応は不要です)

    https://mochimochi-hoppe.hatenablog.com/entry/2023/09/23/125119

    X(旧ツイッター)で話題になっていたのですが、残った行動順の謎も含めて正答らしき検証をされている方がいました。

    現状の実害としては、Pyでは、防御力+1以上持った敵に固定値1ダメージで2ダメージを与えられないため、大量にダメージモーションを積む多段ダメージ系スキルが弱体化しているようです。

    チェック用シナリオ:https://bitbucket.org/akkw/cwpyreboot_pr/downloads/dt202309.zip

    手元ではcalc_defensedvalueの戻り値を以下にすることで一致した感じです(Python3のfloatと除算の扱いの仕様変更で100.0のところはそのままは駄目かもしれません)

    # 小数点第三以下を切り捨て、ダメージ軽減率から実際の軽減値を求める
    buf02 = int(10 * enhance_def)
    dbuf = int(value * (buf02 / 100.0))
    return max(1, value - dbuf)
    

  66. k4nagatsuki reporter

    ありがとうございます。検証をやっていただけるのは本当に助かりますね。

    こちらの方で手を入れてテストする余裕がいまだに確保できないので(連休の時期になんとかなるかと思ったら無理だった)、余裕があるようでしたらPull Requestしていただけるととても助かります。

    除算については、実数であれば結果は変わらないと思います。

  67. Log in to comment