ループの原因を調べたい

個体値と性格値は乱数によって決まるってのはいわずもがなですが、ポケモンで使われる乱数は乱数といっても擬似乱数で、乱数を計算するためのシードが同じなら同じ結果が起きます。


そして、乱数を発生させる式は、seed × [41C64E6D] + [6073] (seedは8バイト)。
結果の下位8バイトを次のシードとし、シードはそのまた次のシードを得るためのシードとして使われます。ただし、実際に乱数として使われるのは、シードそのものではなく、シードの上位4バイトのようです。
したがって、個体値性格値に関するポケモンの乱数は4バイトデータの数列。


で、一部の方法で得るポケモン個体値、性格値の生成は、この乱数列から順番に4つとって、そこから行われるらしい。
まず、乱数を2番目、1番目と並べたものが性格値(性格値は8バイト)であり、
3番目からHこぼ、4番目からすコボが計算されます。
個体値は、乱数を2進数表示にして、(例:0001011101011100)
下から5個ずつ組にする(例:0 | 00101 | 11010 | 11100)
分けたものを10進数に直したものが、| 防御or特防 | 攻撃or特攻 | HPor素早さ になります。上の例ならHP28、攻撃26、防御5。


そして、この仕組みから計算された個体値&性格値は上記のように相関があるため、個体値から性格値を逆算できます。
個体値6つから、ありうる性格値を全パターン検索すると、大抵4つ程度ありえる性格値が出ます。
性格が固定されるポケモン(カード配布とか)だとどの性格値が本当に正しいかは解析しないと不明ですが、性格が固定されないポケモンクレセリアとか)とかだと性格値はほぼ1つに絞れます。
したがって、上記の擬似乱数の式が分かっていれば、個体値&性格からその生成に関わる乱数を逆算できます。


たとえば、以前捕まえたクレセリア個体値データから

個体値×6 性格 ありうる性格値
31,22,21,23,31,30 しんちょう 508F2CCE
20,29,31,19,18,22 わんぱく DC0C4C7D,4C01B753
31,08,10,09,24,17 がんばりや 52B90995
21,29,05,21,03,09 おとなしい 88587D34,894045D3


こんな感じに性格値を逆算できます。
ちなみにありうる性格値を逆算するだけなら、海外のサイトにツールが転がってたので探してみてください(
ただし性格値&個体値の生成方法はいくつかあってそっちの方法でも逆算してしまうので注意。今まで述べたのはmethod1で、他にmethod2,3があります。2,3はどこで使われてるのかいまいち分からないけど。



性格値を実機から求めてにやにやするのもまあいいんですが、個人的に気になるのは、この方法で乱数を逆算してしまえるというところ。
この方法で乱数を逆算すればクレセリアや配布系のループの原因を探れます。


たとえば、上記のクレセリアの1番目と3番目は、2cce1efa、0995d068から始まる乱数列で性格値&個体値が決定されている、というのを突き止めることができました。実際に計算してみると、上記の個体値が生成できることも確認できます。
したがって、似たようにいくつもループ下の個体を解析していけば、ループの原因を起こす原因となる類似部分がいずれ見つかってくるはずです。


ちなみに、上記の2つの乱数列を2進数表示すると
 00 10110 01100 11100 00111 10111 11010
 00 00100 11001 01011 10100 00011 01000
となりますが、各ビットが一致する割合は18/32。ほぼ1/2じゃねーか(
HP同じなら下位1バイトくらいは一致するんじゃないかとか考えてた俺が馬鹿でした。もっとデータが必要そうです…
例のループをご存知の方は、HP31、素早さ30の個体値を持つクレセリアの全詳細個体値と性格を教えてくれると助かるかもしれません(


まあ、別にループの原因が分かっても得はしない可能性が非常に高いですが、
乱数が特定できることにより一応考えられるリターンとしては、


・ループ下でどの程度の個体値まで狙えるかが分かるかもしれない
・時間経過により乱数の消費が行われている場合、高個体値を出すために必要な時間経過を計算で求める足がかりになるかもしれない
・乱数の消費を完全に制御できるとしたら、適切に乱数を消費することで高個体値野生一発でツモれるかもしれない


とかかなあ。夢がひろがりんぐw
書きながら思ったけど、エメループは利用しやすい最強のループになる可能性がありますね。
肝は時間経過と乱数消費かなあ…
エメループの説明に、乱数は起動後経過時間で決まるみたいなことをよく見るけど、個人的には起動時に最初のシードが毎回同じ値に決まって(エメの場合)、時間経過により乱数が消費されることにより、起動後経過時間が乱数の因数のように見えるってだけだと思う。
ちなみに、エメは不明なんですが、自分が見たソースでは、ダイパでは起動時に最初のシードが決定されると書いてありました。おそらく起動後経過時間はカウントしてなくて、時間経過により乱数が消費されていってるだけ、というのが自分の予想。


エメループは、
最速でラティを捕まえまくる→擬似乱数を特定
最速より少しだけ遅くラティを捕まえまくる→こっちも乱数を特定
2つの乱数を見比べて、上記の乱数生成法で最速のほうの乱数を何度か計算に通してみて、最速より遅いほうの乱数が出てきたらビンゴ。時間経過で乱数が消費されていることの証拠になる。
もっと詳しく調べるなら、擬似乱数の1周期に対して、特定した乱数がどの位置にいるかを調べてみる。
んで次は1秒(1F?)あたりどのくらいの乱数が勝手に消費されるのかを調べる。これは既にとった2つのデータの、最速からの遅延時間を計算ステップ数で割ってみるといいと思われる。
ここまで順調にいったら、特定の遅延でどういう個体値が出ると予想できるかを計算で出してみて、実際にやってみる。やってみてこれが成功したら神の領域っつーか、最速めざ地だろうが最速めざ氷だろうが、適切に時を刻めば狙ってゲットできるようになる。ストップウォッチ片手に厳選の時代。倍速GBAよりも0.5倍速GBAが有用になる時代。フレーム単位の精密動作を求めて。
ちなみにサンダー等エメ以外の伝説は基本的にループしないけど、時計を止めてみるとループするようになるはず。ソースは俺のサファイア
難点はデータ取りが大変なわりに机上の空論度が非常に高いところw



あとダイパループが話題になったときに、孵化でもループしないかちょっと試そうと思ったんだけど、データ取りがあまりに大変なので7匹で挫折(
その7匹の中に全個体値一致がいたのは収穫だけど、正直どうでもいいデータな気もする。ただ爺前固定よくやってる人はあまりいい話ではないかも。
HPだけループしやすいとかだったら最高なんですけどねー
HP31のでやすいループを見つけたら、HPの遺伝率の低さもあって強烈なシナジー



以上、妄想でした。間違ってる可能性も高いです
もしこれを見て何か分かったりとかしたら教えてほしいです。
こんなデータ取ったんですけどどうよとか、解析してみたところシードはこんな風に決まってましたよとか、それもう調べたんですけど○○でしたとかでも(
とりあえずエメはエミュでメモリ見てみるのが早いかなぁ。そんなスキルどこにあるんだって話ですがorz



※追記〜
さくっとエメのループを調べてみた。
サンプルを3匹ほど

条件 個体値 性格 逆算した性格値 逆算した乱数 最速の乱数から何ステップ目で一致するか
最速連射 3,31, 5,14, 0,20 わんぱく CC1DBDD8 bdd88b21 x
一瞬連射切る 21,24, 1,22,11 2 れいせい D8354F4F 4f4f51fe 23
手押し連打 25, 4,11,13,20,21 がんばりや DFA2BE87 be871cce 103

予想通りでうれしかった(
頑張れば1Fあたり乱数いくつ消費してるか分かるかも。


※※ついつい
やっぱり1Fごとに乱数一個消費。


0F遅延,29- 5-31- 8-25-16,2ADD01D4
1F遅延,16- 8-25-23-24-16,7CBD2ADD
2F遅延,16-23-24- 3-19-20,E5107CBD
3F遅延,20- 3-19-12- 7-19,62F0E510


ひとつまえのフレームの性格値前半分とその後ろの性格値の後ろ半分が一致。




さくっとめざ地と後ろ3Vを計算させてみた。
めざ地は上記の0F遅延から遅れることおよそ28000フレームのところに1匹無邪気威力69がいらっしゃる。46000フレーム待てば同じく無邪気だけどオール20超え威力67がいる。どっちも下3つが30-22-31。ちなみに特攻or特防30に固定して検索してるから、26-26-31みたいなのがまだいる可能性もあり。
ちなみに1フレーム=1/60秒のはず。3600F=1分w
1/18000程度の確率のものなら5分以内の位置に1匹くらいはいる可能性が高い。


次の実験は実機で狙った個体を出すことだけど、サブエメ紛失中っていうねorz


とりあえず、やり方としては、
1、とりあえず最速で捕まえて個体値と性格をめもる
2、その個体値と性格から、最初の乱数を逆算する
3、最初の乱数から適当に20000個くらい乱数を生成させてみる
4、作った乱数から上記の方法で個体値&性格を計算してみる
5、出てくる個体値の組は20000個。ここからほしい個体を探す
6、探したら、それが出てくるフレームを調べる
7、実機で、最速からフレーム数×1/60だけ遅らせて捕獲。
8、もちろんフレーム単位の精密動作は無理なので、ある程度近い位置に修正しつつ、数うちゃ当たる方式で試行を繰り返す。


たとえば、この方法で最速の60フレーム後に超強いやつがくるって分かったら、最速より1ちょうど1秒遅くエンカウントするようにすれば、その超強いやつと遭遇できる、って感じかな。


とりあえず、最初の乱数を入力したら、好きな個数だけ性格&個体値を計算するプログラムを作りたい。そのデータさえ出力できれば、あとはエクセルかなんかで適当にやれば、目当てのものを探すのが非常に楽になるはず…