Em孵化で存在しない性格値
アドカレ支援のために128日目の記事ということにします。 エメラルドの孵化における性格値の生成処理の擬似コードは以下の通り
code:gen_pid.cs
var f = (uint)GBA.GetFrameCount(); // フレームカウンタの値を16bitで取得する
var hid = f.GetRand(); // フレームカウンタの値をseedとしてLCGで乱数を1個取得し、性格値上位16bitとする
var lid = seed.GetRand(0xFFFE) + 1; // 0x0000 ~ 0xFFFDの範囲で乱数を取得し、+1したものを性格値下位16bitとする
pid = (hid << 16) | lid
LIDの範囲が0x0001 ~ 0xFFFEとなることから、下位16bitが0000やFFFFになるような性格値が存在しないことは以前から知られていた。
下に追記有り。
フレームカウンタとseedの関係性は画面描画ごとの消費以外の消費によってずらすことができる(いわゆる『差分』)ため、HID生成とLID生成は独立して考えてよい(つまり、HIDとLIDは特定の組み合わせでないといけない、というようなことはない)。
現時点でフレームカウンタとseedの関係性を変動させる方法として確立されているのは『マップ描画の際に発生する3消費などを利用する方法』だが、BVや絵画を見ることでseedの書き換えを発生させることによってもこれは行える。大変な割にメリットが薄いのでいまだ実用には至っていないが。誰かやってもいいのよ。
一方でHIDにも実は制限がある。16bitの値を元にLCGを1回回して乱数を得ているため、取り得る値のパターンが65536通りに満たないのである。
計算してみたところ、実際に存在するのは45880通り(≒70%)だけだった。実に19656通りも存在しないHIDがあるのだ。びっくり。
存在しないHIDの中にはFFFFやFACEなどがあった。0000やCAFEやBEEFは存在していたのでごあんしんください。
2024/6/9追記
変わらずの石を持たせた場合は生成処理が異なることを見落としていました。変わらずの石が発動した場合はlid = seed.GetRand()で生成されるため、0000とFFFFも生成され得ます。