学習システム

人間は成功から効果的な手段を、失敗から悪い手段を学習して、同じ成功を増やし同じ失敗を減らせるが、
コンピューターはプログラムで決められた通りにしか動くことができないため、効果的な手段をプログラム通りにしか使えず、
悪い手段ばかり使ってしまって同じ失敗を繰り返し、悪いパターンにハマってしまうことが珍しくない。
そこで成功や失敗を記録し効率的な手段や逆効果な手段を判断させて、悪い手段を減らすといったプログラムを組み、
同じ失敗でハメられるといったことを回避しつつ、効果的な手段を使わせたりするのがコンピューターの学習システムである。

比較的有名なケースとしてFCの『ドラクエIV』では、第5章の主人公以外のメンバーに直接行動指示が出せず「ガンガンいこうぜ」など、
漠然とした命令にCPUが従うというシステムだったので、有名な「ボスにザラキを何度も使うクリフト」といった無駄な行動が発生していたが、
実はちゃんと戦闘終了(敗北も含む)時に「ザラキはこいつには効かない」などとCPUが学習していたりする。
(ただし、あくまで「その敵について」のみ学習なので「ボスは全員ザラキ無効」などは最後まで分かってくれない。
 また、最終ボスの第一形態~最終形態に至るまでの数回の戦闘は全て別の敵扱いなので、それぞれに学習させないといけない。
 しかも、通常の敵であってもザラキが効かない敵に対してザラキを使った直後に別の攻撃で倒した場合、「この敵にはザラキが効く」と誤って認識してしまう。)
また、実際に学習しているのかどうかは不明だがジョイメカファイトではCPUが時々行動パターンを変えてくることがあり、
一見こちらの手を読まれている(例:ハメ技が破られる)ように感じるためか、これを「学習」と呼んでいるプレイヤーもいる。


MUGENでは

失敗などを記録して同じ失敗を減らしたりするためのAIのシステムを指す。
学習システム以外にも、擬似学習、学習機能、学習ロジック、学習装置、記憶システム、記憶装置など
様々な呼び方をされているが、基本的に全て同じものである。特に学習システムが使われているAIは学習型AIとも呼ばれる。
このページではプログラム上の学習・記憶を 記録 と、プログラム自体は 学習システム 、あるいは ○○学習 と表記して統一する。
(一応、失敗記録以外も学習システムといえば学習システムである)

様々なキャラの入り乱れるMUGENでは色々な相手と対戦することになるが、
AIは相手の情報をあまり知ることができず、AI殺しなど対応しきれない部分が多く出てくる。
しかし相手に合わせて予め情報を入力することも難しいため、失敗などをVarに記録することで
相手に合わせて対応を変更するという学習システムを備えたAIも多く存在している。

ただ一口に学習システムと言っても種類があり、それぞれで別々の情報を記録していく。
例えば技の失敗回数を数えてその行動を減らすという程度のものも、一応学習システムの一種。
複雑なものだと 対攻撃学習システム で相手の攻撃を記録して、より早い攻撃や無敵技で潰しにかかったり、
的確に当て身投げをしてくるAIも存在する。流石に大抵設定で自重させることもできるが。

また便利な学習システムも記録を保持できるのは その試合中のみか、そのラウンド中のみ で、
一試合毎か1ラウンド毎に 記録がリセットされてしまう といった欠点があり、
記録Var数の問題もあってなんでも記録できるというわけではない。
なんでも記録できて試合後も残せたらそれはそれで問題だが…
(Var:変数。砕いて言うと、数字を書き込めるメモ用紙。新しい試合では新しいメモ用紙を使う。)

Helperとラウンド引き継ぎについて

Varや処理の関係上、複雑な学習システムにはHelperを使うことが多い。
複雑な記録には相応にVarを多数必要とするので、本体の空きVarだけでは足りなくなってしまうからである。
またVarだけでなく、記録内容と処理の関係でHelperでしか記録できない場合もある。

しかしHelperはラウンドをまたぐと消滅するため、Helperだけで引き継ぐことはできない。
1キャラがラウンドをまたいで引き継げるVarは本体のVarの計100個までなので、
本体側に移して引き継ぐにしても引き継げる情報量には限界があり、
ラウンドをまたぐと記録がリセットされてしまうのはしかたないのである。
(Helper:分身。画像を飛び道具すれば飛び道具になるし、表示させずに使うこともできる。Varは本体と同じ数。)

学習システムにおける注意点

複雑な学習システムを作って導入することは難しく手間がかかる。
汎用的なシステムは一度作ってしまえば流用できるものの、複雑な学習システムを
1から作るとなると簡単なAIを1つ作るくらいの知識と労力が必要になることもあるほど。
その上、相手の処理が特殊であったり、記述が甘かったりすると誤作動を起こす危険もあり、
しかも同じ状況が来ることが前提であるため、同じ状況が来ない場合は宝の持ち腐れとなる。
相手の攻撃を記録する学習システムだと必殺技の強弱などの違いを認識できない場合があったり、
それ以外にもタッグ戦などでは攻撃が入り乱れるためほとんど役に立たないことも多い。

学習システムはあくまで通常の記述では至らない部分を補うだけで 万能のシステムではない のだ。
凶悪な学習システムを積んだからといって、それだけでAI全体を補うことはとてもできないし、
それに 複雑な学習システムが無くとも十分に優秀なAIもある
例えば学習システムが無くとも多彩な動作をさせておけば悪いパターンにハマることを減らすことはできる。

動画的には単純なミスを何度も繰り返すよりはミスを修正して上手く戦っている方が見ていて楽しいですし、
対攻撃学習システムも記録の溜まった後半から逆転するといった魅せプレイをしてくれることがあります。
もちろん相手を封殺するといった場合もありますが、それでつまらないと感じても学習システム自体が悪いのではなく、
学習とは関係無く単純に両者の強さが合っていない試合は他に面白いことがなければつまらないだけです。
特に対攻撃学習システムなどは強さを大きく跳ね上げることもできますので、
制作者も使う側もいつもの強さという思い込みに囚われず実際の強さに注意しましょう。
(強さの思い込みについては学習システムに限った話ではありませんけど)


主な学習システムの種類

専門的な話は割愛。StateNoなどちょっとした用語には補足を入れています。
(StateNo:動作の番号。同じキャラの同じStateNoでは大体同じ動きをします。)

攻撃失敗学習システム
攻撃が上手く当たらなかった場合や潰されたことを記録し、
同じ攻撃を繰り返して同じ失敗を繰り返さないようにするための、比較的簡単な学習システム。
用途によって○○失敗学習とも呼ばれる。コンボならコンボ失敗学習、投げなら投げ失敗学習。
学習システムと呼ばれることは少ないかもしれないが、一応一種の学習システムである。
全ての技で記録することは面倒であるため記録する対象は主に投げ技やコンボで
投げ技の入らない相手へ投げ技を繰り返させないようにしたり、
うまくいかなかったコンボルートを止めて別のコンボルートを選ぶというもの。
(コンボルートの変更はコンボルートを複数用意できるキャラに限るが。)
基本的な手順は
  1. どの攻撃をしているか確認する。
  2. その攻撃からくらい状態になったり、あるいは攻撃が当たらなかったら失敗を記録する。
  3. 失敗記録のある攻撃を控える。失敗回数が多ければ使わない。
全ての技を調べずとも、直前に潰された技を記録してその技を控えるだけでも単純なパターンなら多少抑えられる。
ちなみに成功回数を記録して効果的な手段を増やすことも一応できるが、パターンが顕著になってしまいやすいので、
失敗回数を減らしたり、通常投げの決まる相手に超必殺技の投げを使うようにするといった程度に留めるべきである。

ガード失敗学習システム
ガード失敗時に自分の状態と相手の技を記録して同じ技で崩されないようにする学習システム。
単にガード学習、あるいは中下段学習とも呼ばれる。
AIは立ち・空中下段や屈み中段、ガード不可技などへの対応が困難なためよく使われている。
基本的な記録の手順は以下のとおり
  1. 相手のStateNoを記録、監視する。
  2. ガードしているかどうかとガードの立ち屈みのどちらかを記録する。
  3. 相手の攻撃を受けて、自分がガード食らいであるかどうか確認する。
  4. ガード食らいでない場合は相手のStateNoと立ち屈みのどちらだったかを記録する。
  5. 記録した攻撃と現在の攻撃のStateNoが同じ場合、その時のガードとは別のガードをする。
  6. 再びガードからガードくらいになった場合、ガード不可として記録する。
  7. ガード不可の場合、ガードをさせない。
ただし飛び道具の中下段やガードクラッシュなど処理が特殊な場合の記録はかなり難しく、
その他ガード不可を認識するためには2回も崩される必要があるなどの欠点がある。
自分の防御力がであったり火力の高い相手だとその2回が致命的になってしまうのだが…

対当て身投げ学習システム
当て身投げを受けた時に相手の技を記録して、同じ技にかからないようにするやや珍しい学習システム。
AIは通常相手の当て身投げを認識することができないため使われることがある。
基本的な手順は
  1. 相手のStateNoを記録、監視する。
  2. 自分の攻撃をReversaldefで取られた直前の相手のStateNoを記録する。
  3. 同じStateNoの攻撃を相手がしてきたら、攻撃をしないようにする。
  4. できるなら当て身投げ動作の終了直前(受付が終わった後)を狙った攻撃を仕掛ける。
回数の少ない超必殺技の当て身投げや攻撃に反応しての当て身投げには機能しにくいが、
露骨な当て身投げに当て身投げ見てから攻撃余裕でしたと言うことを減らすことはできる。
(ReversalDef:主に当て身投げ用の命令。)

対投げ学習システム
投げ技を受けた時に相手の技などを記録して、同じ投げにかからないようにする珍しい学習システム。
投げは基本ガードできないが通常EnemyNear,HitDefAttr=SCA,ATなどに超反応で避ける以外に確実な回避方法がなく、
攻撃判定枠の発生が遅くてもHitDefの発生が最初からの場合、最初から反応してしまう。
それに攻撃の発生が0~1フレームの場合は反応が非常に難しいため回避すること難しい。そこで、
  1. 発生の非常に早い投げ技を受けた時にその技の距離を記録する。
  2. 相手と距離を取ってその間合いには無闇に入らないようにする。
といった方法であれば自分も近づきにくいが、投げられにくくはなる。こちらは別名、1F投げ警戒。
またHitDefのタイミングが違うことで反応がバラつくのは
  1. 相手のStateNoと始動からの時間を記録、監視する。
  2. 相手の投げ技を受けた時にStateNoと発生フレームを記録する。
  3. 相手が同じ投げ技をしてきた場合、発生フレームに合わせて無敵技を出す。
という方法なら安定して相手の投げ技に切り返すことができる。
もちろん早い投げ技まで確実に切り返すと凶悪な超反応になってしまうが、
相手の動作時間も確率に含めて適度に切り返すようにしている場合もある。
(EnemyNear,HitDefAttr=SCA,AT:近くの相手が投げの攻撃判定(HitDef)を出しているかどうか、という条件
 HitDef:攻撃判定。これがないと攻撃が当たらない。)

対攻撃学習システム
冒頭でも話題にしていた、相手の攻撃を記録して当て身投げや無敵技を出す凶悪な学習システム。
大体敵攻撃フレーム学習、当て身投げ用学習、技学習などと呼ばれる。
他の学習システムが基本的に失敗を記録するのに対してこのシステムだけは
失敗していなくても(ガードしても)作動し 相手を圧倒することも可能になる というシステムである。
基本的な手順は対投げ学習のタイミングによる学習と同様
  1. 相手のStateNoなどの情報を記録、監視する。
  2. 相手の攻撃を受けた時、相手の攻撃の情報を記録する。
  3. 同じ攻撃がきた場合、発生までのフレームに合わせて技を振る。
距離も記録して判別すれば、遠くから突進してくる技の距離の違いでタイミングを外されるといった危険を少なくできる。
こちらも確実に反応すると凶悪な超反応になってしまう。
実際のAIでは動作時間などでの確率が調整されている場合もあるが、AI設定を最大にすると容赦無く返してくることも。
正確に数値を記録できていれば、受付が1フレームの当て身投げでも成功させることができるが、
技によっては反応しても当て身投げできなかったり無敵技での回避もできなかったりすることもある。
対攻撃学習と対投げフレーム学習の実演動画。
容赦無く反応する実践に上手くいかない実践もあり。

  • 対投げ学習・対攻撃学習: HitDefAttr認識型
対投げ学習や対攻撃学習を、攻撃を受けずとも記録できる方式。
慣例的に攻撃判定枠が出るタイミングでHitDefも出されていることを利用し、
Enemy(x),HitDefAttr=SCA,AAなどで相手のHitDefの出たタイミングを認識することによって、相手の攻撃発生を記録する。
これならば攻撃を受けることなく発生タイミングを知ることもできるのだが、対投げ学習のところにも書いているように
HitDefの発生が最初からだったり、攻撃判定発生前の途中からだったりすると正確な認識ができない。
一応慣例から大体最初からか攻撃判定と同時かのどちらかなので、途中からのだけを記録すれば大体正確な記録になるが、
攻撃の距離などは分からないため、突進するタイプの技が自分に届くタイミングなどまでは分からない。
しかし回避技で攻撃を避けて記録をして、記録から相手の攻撃を潰せば 完全封殺することも可能 な記録方法ではある。
(Enemy(x),HitDefAttr=SCA,AA:相手が打撃の攻撃判定を出しているか、という条件。)


ちなみに
上記のような学習システム以外にも、立ち回りレベルの事を記録する学習システムも作れる。
効果が細かい調査の労力に見合うかは別だが、傾向程度の簡単な記録なら丁度いいかもしれない。
(相手が素早い接近技や遠距離への攻撃を持っているなら遠距離で隙のある技をあまり出さないだとか、
空中動作の挙動の空中ダッシュや空中ジャンプがあるかどうかなどを記録し対空の確率調整に使うなど。)

記録の難しいものや状態などについて

記録できれば人間では不可能な性能を引き出せるが参照の難しいものは記録も難しく、学習システムも作りにくい。
例えば攻撃・くらい双方の判定枠の精確な形を知ることは通常不可能で、対攻撃学習でも当たった距離までしか分からない。
特に飛び道具はただでさえ参照することが難しく、性質が多彩であるため記録が非常に困難。
そのため飛び道具反射技を的確に使いこなせるのは人工AIくらいなものとも言える。

反対に言えば例え高精度の対投げ学習や対攻撃学習などを搭載した凶悪な学習型AIが相手であっても、
飛び道具や設置と打撃をうまく重ねれば記録や反撃の難しい攻撃となるため、学習型AIを圧倒できる可能性すらある。
それ以外にも多くの種類の技を使っていけば学習システムの容量が限界に達することもあるので、
技が多ければそうした正攻法で対抗できる可能性はある。物によっては数十個の記録をしてくるが…
他の対抗方法としては、数回触れるだけで相手を倒しきれるキャラなら記録を発揮される前に勝てることも。

無敵のある技やアーマーなども通常相手の無敵などの状態は分からないため、AI制作者たちを悩ませている。
+※それらに対する未開発の技術について
※未開発です。推測と主観入り交じってますが、一種の案として。

対無敵学習システムについて
現状p2Name以外、 かなり困難 だと言われている。
無敵のある技は攻撃が当たる範囲で当たらないことを認識しても、それが無敵のある技なのか、
それとも判定小さかったり、動いていたりしてが届いていないだけなのか分からないのである。
とはいえ、その記録を繰り返すことで大体の認識も出来なくはない、と思う。
  1. 相手のStateNoなどの情報を記録、監視する。
  2. 相手がくらい状態でないことと起き上がりの直後でないことを確認する。
  3. 自分の攻撃の判定が出ている時(AnimElemNo(0)=x)、相手が攻撃範囲(X,Y両方)にいるか確認する。
  4. 範囲内なのに判定が終わるまでに当たらなかったら、相手のStateNoを記録し、回避された回数を数える。
これを繰り返し記録していくことで、その技には基本的に攻撃が当たらないとある程度認識できるはず。
基本的に、ある程度と言うのは、特殊な仕様や発生無敵などは認識ができないため。
相手の攻撃状態も除外することで、回避動作のみに認識を絞った方がいいかもしれない。
ちなみに大半の前転や阿修羅閃空などの回避動作は相手をすり抜ける性質があるので、
  • 自分が地上で衝突判定があり、相手も地上で攻撃状態でない時。
  • 相手が自分と重なって通過された場合、相手ののStateNoと記録し、その回数を数える。
これを繰り返し記録していくことでも、ある程度は認識できるかもしれない。かなり面倒だが。

対アーマー学習システムについて
現状p2Name以外、細かい判断は 基本的に無理 だと思う。
一切仰け反らないしステートも奪われないハイパーアーマーとそれ以外の判断はできるものの、
それ以外のアーマーがどういった仕様であるのかはp2Nameを使わない限り無理である。
と言うのも、投げ耐性のみで仰け反りのあるアーマー、反対に投げることはできるアーマー、
常時展開ではなく制限時間や耐久度のあるアーマー、アーマーのある攻撃などの場合、
ブロッキングや関係のないヘルパーのくらい判定などと区別を付けることは難しすぎて無理だ。
しかし一切仰け反らないしステートも奪われないハイパーアーマーだけは別。
例えば攻撃が当たった(MoveHit)回数を記録して、近くで攻撃してそこそこ当たっているはずなのに、
相手が一切くらい状態にならない状態はハイパーアーマーか全開アレクブロッキングくらいである。
一応独立したヘルパーのくらい判定である可能性もあるが、数回攻撃しても同様の状態なら可能性は低い。
(分身に攻撃している可能性もあるにはあるが、その場合は本体がくらい状態になれば判明する。)
そこから更に相手のStateNoとTimeの動きを監視すれば、ヘルパー型のアーマーなのかそれ以外かが大体分かる。
いくら当てても平常に動いているのはヘルパー型アーマーだけなのでハイパーアーマーでほぼ確定する。
HitOverrideによるブロッキングとアーマー処理の区別は付きにくいが、
StateNoの行き先がいつでも一定の場合はブロッキングの可能性が高いと判断できる、はずである。
もちろん、ハイパーアーマーだと判断してからも相手がくらい状態になったりした場合は、
条件付きアーマーや分身、ブロッキングのどれかなので、ハイパーアーマーだという判断を消す必要があるが。
しかしそんな面倒なことをせずとも攻撃失敗学習システムなどを用いることで、
アーマーの相手も含めて 相手に合わせた動作にすることは可能 である。
  • 攻撃ヒットからコンボ動作に行けないという失敗が積み重なればコンボを止めさせればいいし、
  • 投げを何回やっても掴めないのなら、単純に投げ技を止めさせればいいだけのことである。
(コンボに関してはNumtargetやEnemyNear,MoveType=H、EnemyNear,StateNo=[5000,5099]などで
 相手の状態をしっかりと認識させて判断させればアーマーにコンボを試すことは無いかと。)
学習システムはなにも複雑なシステムを作らなければならないわけではない。
単純な単一の技の失敗を記録してそれを控えさせるだけでも効果的な学習システムになりえる。
もちろん別の選択肢となる動作の制作は面倒ではあるが。

対無敵学習システムと対アーマー学習システムについてへの補足
HitDeffのground.type=nonを利用した無敵やアーマーの計測が可能で実際にいくつかのキャラに搭載されています。
ground.type=nonに設定された攻撃は相手にヒットしても攻撃を受けた側も攻撃した側も攻撃がヒットしたと認識することができません。
更に攻撃がヒットしても何も起こりません。しかし攻撃した側のP1StateNoは効果を発揮します。
その為、Helperによるground.type=nonの攻撃がヒットしたときのみに特定のStateにそのHelperを移動させることができます。
このHelperのStateNoを監視することで相手に攻撃が当たるか当たらないかを判断することができます。
攻撃が当たらないということは無敵状態に加えてHitOverrideによるブロッキングの受付中や食らい判定を持ちStateを奪う攻撃を無効にしたHelperアーマー等も含まれることになります。
無敵なのかブロッキングなのかアーマーなのかはLifeの減りや他の攻撃が当たるのか等のいろいろな要素も監視して判断する必要があります。
 一見、穴が無い判定のように見えますがこの判定方法には大きな欠点があります。
HitDefは後からヒットした情報に上書きされるという性質がありこの性質はground.type=nonに設定されていても同一フレームだと発揮されてしまいます。
これにより同一フレームでこの計測用のHelperの攻撃の前に別の攻撃が当たっていたときに仰け反り時間やダメージなど、
HitDefのすべての情報を計測用のHelperの攻撃で上書きしてしまい本来の攻撃が想定していた性能を発揮できない不具合が出てしまいます。
その為、自分が攻撃中やタッグのときの味方が攻撃中のときは測定を停止しないと不具合が出てしまいます。
この攻撃中というのは自分や味方の飛び道具や設置も含めるため攻撃中は計測しないというのをタッグにも対応させるには、
HelperのPlayerID検索によりすべての攻撃性能を持つHelperの監視もしなければいけません。
 このような制約はありますが攻撃の属性ごとに判定することで以下の例のようなことが行えます。
  • 避けなどをしている打撃無敵状態の相手に打撃牽制を振らないで投げる
  • 投げ無敵状態の相手に投げ技を出さない
  • 前転中を投げたり終わり際に合わせてコパンを擦る
  • タッグ時に味方へロック技を仕掛け演出中の相手へ無駄な攻撃を連打しない
  • アーマーへの有効な反撃を選択する
などピンポイントでの状況判断ができます。
ただしピンポイントでの計測に特化してるため学習する必要自体があまりありませんが・・・。
 また、無敵計測=攻撃が当たる状態を計測するため計測のための攻撃判定の大きさと位置により上半身無敵なども判断できます。
応用で身長の計測やフレーム単位の制御が必要でかなり手間はかかり実用性はあまりありませんが、
学習を組み合わせて相手の周囲から小さな点状の攻撃判定を移動させながら計測することで食らい判定の大きさも記録することができます。

記録と記録量について

情報の少ない学習システムは別々のAI制作者でも記録の大きな違いは少ないが、
情報量の多い対攻撃学習システムなどでは記録する情報に大きな差があることも。
相手の攻撃フレームだけ分かればいいなら、StateNoと発生フレームだけでいいが、
距離や反応の失敗、直前のStateNoなどまで記録しているシステムもある。

記録する情報が多ければ精確な判断ができる分Varを多く使うため記録数が少なくなってしまい、
反対に記録する情報を限れば記録数は多くできるものの判断の精度が若干落ちるため一長一短。
少なくても始動のみの10個程度の記録、多いと80個の記録をするシステムも存在するらしい。
ただ多数の記録が必要無い対当て身投げ学習などは情報が少なくても記録量も少ないことも。
冒頭でも言った通り一口に学習システムといっても、様々な種類があるのだ。


対学習システムキャラ

学習システムを作る上で気をつけておきたいものは、 学習システム殺し である。
攻撃を学習する学習システムを騙すことは意外と単純なこと で特殊な技術を使わなくても騙せる。
1つの技のステートを別々の番号で20個ほど用意 して順番に使っていけば、
相手の攻撃を記録する学習システムは全て 別々の技だと記録 してしまい、ほとんど反応できなくなる。
Animで記録していることを想定するなら別々のAnimも用意すればいい。
それ以外にもちょっと面倒で技術が必要だが、下段の技と中段の技を 同じStateNo で処理させれば、
単純なガード失敗学習システムもガードの判断を誤り、やがてガード不可だと判断してしまう。
中下段だけでなく別々の技を 同じStateNo で処理されると、
相手の攻撃を記録する学習システムは全て 同じ技だと判断 し、正確な反応ができなくなる。
動作の時間をTimeなどで管理し、同じAnimに別々の動作を入れてElemを動かせば、Anim記録でも判別がつかない。
(Anim:表示させてるアニメの番号。 Elem:アニメの一枚一枚のこと。 Time:時間。)

ちょっと大げさかもしれないが、もし無思慮で凶悪な学習システムが氾濫した場合、
学習システムをキャラ側の調整で 無効化させられる 可能性もありえるということを肝に銘じておこう。
とはいえ、あくまで学習システムも強さの一部で、強さを見誤らなければそれほど酷い試合は繰り返されないだろうが。

学習システムの凶悪さに拘わらず、探究心や好奇心で作る製作者もいるかもしれないが、
例えば表示アニメが同じで人間には判断が難しい別々の技を同じステートに入れ、
AI的にも判断の難しい技にすれば、学習型AIがあたかも騙されているように動いてくれることもある。

ちなみに特殊な処理で学習システムが判断を間違えるということはそこまで珍しくない。
と言うのも強弱のある必殺技は同じステートで処理をしている場合があり、その強弱の判別は難しく、
それ以外にも溜められる攻撃を1つのステート内で処理している場合などは、溜め時間を認識できない。
そうしたちょっとした違いでも反応を間違えることはあるため、記録する側は反応の失敗回数も記録させておくほうが無難。