奥が深いポケモンのダメージ計算
みなさんアローラ!今回は、以下の企画に参加する形で書いていきたいと思います。
テーマは「ゲーム版ポケモンにおけるダメージ計算」についてです。
すでに多くの計算ツールが世に出回っていますが、本当に信頼できるのか?と疑ってしまう方もいると思います。 私も疑り深い性格のため、レーティングに向けてダメージ計算ツールを自身で作成することがあります。 その実装の際に興味深いことが多くあったので、今回は記事としてまとめてみたいと思います。
ダメージ計算式について
知ってる方も多いと思いますが、以下がよく見る計算式となります。 (※ 乗算を「*」、除算を「/」で表現しています。)
[{ ( 2 * 攻撃側のレベル ) / 5 + 2 } * 技の威力 * 攻撃力 / 防御力 / 50 + 2] * (0.85 ~ 1.00)
これだけを見ると、「各ステータスの値を正確に入力すれば、正確にダメージが計算できそうだ。」と思われる方が大半だと思います。 手によって計算する場合はその通りです。しかし、プログラムを作成すると計算結果が大きく変わる罠が含まれています。 これから、その罠について紹介していきます。
ダメージ計算式の罠
その1 数字の表現方法
ポケモンの戦闘では、「いのちのたま」や「ヤチェのみ」といった道具によってダメージが増減します。 また、「フェアリースキン」や「もふもふ」といった特性によってもダメージが増減します。 一般的には、これらのダメージ増減を「1.5倍」であったり「0.5倍」と表現します。 しかし、ゲームの計算では以下のように表現されています。
- 2倍
( * 8192 / 4096 )
- 1.5倍
( * 6144 / 4096 )
- 1.2倍
( * 4915 / 4096 )
- 0.5倍
( * 2048 / 4096 )
2倍を例にすると、元々の数値に8192を乗算し、その結果を4096で除算するということになります。 注目して頂きたいのが、1.2倍の表現です。 「4915 / 4096」を計算すると「1.199951171875」となります。つまり1.2の近似値です。 このようにゲーム内では特定の数値を近似値で表現しているため、1.2という数字のまま計算したケースと比べると結果が異なる可能性があります。 ダメージ計算ツールを作成する場合は気をつけなければなりません。 (※ビット演算で調べると、なぜこのような方法で計算しているのか分かりますよ!)
その2 小数点以下の扱い
ポケモンに出てくるステータスは全て整数です。そのため、計算した結果に小数点以下の値が含まれると都合が悪くなります。 そのため端数を処理する必要があるのですが、ポケモンでは以下の3つの方法が取られます。
- 切り捨て
- 整数部分をそのまま残し、小数点以下を0とする
- 四捨五入
- 端数が0.5未満なら切り捨て、0.5以上なら切り上げる
- 五捨五超入
- 端数が0.5以下なら切り捨て、0.5を超えていたなら切り上げる
この3つの端数処理を適切な場所で行う必要があります。 しかし、プログラムの世界では何も考えずに作成すると端数は全て切り捨てられます。 そのため、ここも重要なポイントとなります。
さらに、端数処理が行われるタイミングも重要です。 冒頭に紹介したダメージ計算式では、以下のタイミングで端数処理が行われます。
{ ( 2 * 攻撃側のレベル ) / 5 + 2 } = A (切り捨て) ( A * 技の威力 * 攻撃力 / 防御力 ) = B (切り捨て) B / 50 + 2 = C (切り捨て)
なんと3回も切り捨て処理が行われます。これを見ると結果が大きく変わりそうだと実感できると思います。
その3 道具や特性の適切な計算位置
ゲームのメニュー画面を見ると、ダメージを増減する道具や特性がどこに影響するのかは説明されています。 しかし、その説明文が非常に紛らわしい場合があります。
例えば「あついしぼう」の場合、「ほのおタイプ、こおりタイプの技の威力が半減する」という説明文になります。 素直に読み解くと、威力40の「ひのこ」が威力20になって計算されると理解できます。 しかし実際には、攻撃側のポケモンの「とくこう」に「2048 / 4096」を乗算して、四捨五入を行います。 以下で具体例を見てみましょう。
攻撃側のレベルが50、「とくこう」が91であり、防御側の「とくぼう」が50の場合 ○「ひのこ」の威力を20とするパターン { ( 2 * 50 ) / 5 + 2 } = 22 ( 22 * 20 * 91 / 50 ) = 800.8 (切り捨て) = 800 800 / 50 + 2 = 18 ○とくこうを半減するパターン とくこう = 91 * 2048 / 4096 = 45.5 (四捨五入) = 46 { ( 2 * 50 ) / 5 + 2 } = 22 ( 22 * 40 * 46 / 50 ) = 809.6 (切り捨て) = 809 809 / 50 + 2 = 18.18 (切り捨て) = 18
最終的なダメージは同じとなりますが、計算の途中で最大9の差が生まれています。 今回は非常に簡単なケースのため最終結果が同じになりましたが、 その他の要素が絡むと容易に最終結果が変わります。 全ての特性・道具の計算を適切な位置で行うことも重要です。
ちなみに、似た特性である「たいねつ」は「相手のポケモンのほのおタイプの技の威力を半減する。」と記載されています。 「あついしぼう」と同じ位置で計算すればいいと思いがちですが、こちらは技の威力に「2048 / 4096」を乗算して、四捨五入を行います。 (なんということでしょう…)
まとめ
今回は、ポケモンのダメージ計算式の罠についてまとめました。 普段意識することなくダメージを計算しているみなさまが、少しでも興味を持って頂ければ幸いです。 また、数少ないポケモンツール開発者のみなさまにおかれましては、非常に気をつけて頂きたいポイントです。 釈迦に説法のような気がしますが…。
p.s.
今回の計算式は以下を参考にさせて頂きました。ありがとうございます。 XY世代専用 ダメージ計算式調査スレッド