ポケットモンスター シールドを発売以来ずっと遊んでいて、バトルでいろいろ試したいなーと思ったので、2ヶ月くらい可処分時間のほとんどを開発に突っ込んでバトルシミュレーターを自作した。
残念ながら、権利まわりがとても怖いのでソースコードやデータは公開していない。
このエントリでは、自作したバトルシミュレーターの画面をお見せし、苦労した点について書く。
開発に使ったのはPython 3.7で標準ライブラリのみ。
行数は全部で5,000いかない程度。
ロジックとデータは別々のリポジトリで管理している。
データはローカルのSQLiteにインポートして、Pythonから読み込んでいる。
もちろんデータも自作した。
ポケモンバトルには1匹ずつポケモンを出し合って戦うシングルバトルと、2匹ずつ出し合って戦うダブルバトルがある。
ダブルバトルは遊んでいないので、今回はシングルバトルだけを考えることにした。
ポケモンにはパラメータが多い。
ポケモンのステータスに関するものだけでも種族値、個体値、努力値と呼ばれる3種類があり、そこに性格や特性や道具の効果が影響する。
ステータス以外だとタイプがある。
タイプには、ポケモン自身が持つタイプ(2個まで)と、技のタイプがある。
タイプ相性によって「効果は抜群だ!」となったり「効果はいまひとつのようだ...」となったりする。
タイプは現在18あるので、相性はその掛け算の数だけある。
加えて、技のタイプがポケモン自身のタイプと一致していると技の威力が1.5倍になる。
技には物理、特殊、変化の3つの区分があり、例えば「やけど状態」だと物理攻撃のダメージが半分になるといった仕様がある。
やけどを挙げたが、いわゆるステータス異常には2種類あって、ポケモンを交代しても継続する状態異常と、ポケモンを交代すると解除される状態変化がある。
状態異常には、やけど、まひ、こおり、どく、もうどく、ねむりがあり、状態変化には、のろい、やどりぎのタネ、こんらんなどがある。
この時点ですでに複雑というのがわかっていただけると思う。
しかし、考えるべき要素はまだまだある。
ポケモンはそれぞれ「特性」を持っており、例えば特性「ふゆう」を持つポケモンにはじめんタイプの技が当たらない。
一見するとひこうタイプと同じように思えるが、特性「かたやぶり」を持つポケモンのじめんタイプの技は当たる。
「かたやぶり」は特性を無効化する特性なのだ。
しかし、全ての特性を無効化するわけではない。
このようにポケモンバトルは例外が多い。
例外対応は面倒だ。
しかしもっと面倒なのが、データの設計だ。
ポケモンの技には様々な追加効果がある。
追加効果には先に挙げた状態異常と状態変化がある。
追加効果の「何が」だけでなく、「いつ」にあたる発生確率や発生タイミングをデータで上手く表現しなければならない。
今回は、追加効果ごとにデータを定義し、対応するクラスを定義する形をとった。
今見たら対応したものだけでも100種類以上あった。
そこからは、どの技がどの追加効果を持つか、ひたすら手入力していく泥臭い作業だ。
何度も心が折れそうになったが、バトルで負けるたびに悔しさを開発のモチベーションにした。
もう一つ面倒だったのが、道具と特性の表現だ。
道具も特性も同じ効果を持つものはほぼない。
例えば、道具の「こだわりスカーフ」は、こだわりスカーフを持つポケモンが最初に出した技しか出せなくする代わりに、素早さが1.5倍になる。
「オボンのみ」は、持ち主であるポケモンのHPが半分になったとき、最大HPの1/3だけHPを回復する。
このくらい、道具であれば「道具である」以外に共通点がない。
道具も特性も、技の追加効果と同じように1データ1クラスという形で一つ一つ温もりの手作業で対応した。
ポケモンバトルのシミュレーターを作ったのには、実はもう少しちゃんとした理由があった。
コマンドラインで動けば、機械学習を使ってAIを作れると考えたからだ。
Pythonを選んだのも、ライブラリが豊富で機械学習と親和性があるからだ。
囲碁AIのAlphaGoみたいに、強化学習でひたすら対戦させて最強のAIを作れればと思っていたが、さらにここからAIを作る気力はもう残っていない。
機械学習は計算リソースがかかるし、ポケモンバトルは修羅の道だし、また気が向いたら挑戦するかもしれない。
コメントを送る
コメントはブログオーナーのみ閲覧できます