DPt/HGSS乱数調整解説 乱数の仕組み

DS版ポケットモンスターにおける乱数の仕組みとその利用方法について書きます。
HGSS版の違いは赤字で書いてあります。

・-1.ツール類
・0.用語
・1.DPt,HGSSにおける乱数
・2.遭遇乱数列の消費契機
・3.タマゴ乱数列の消費契機
・4.共通初項(初期SEED)の決定方法
・5.遭遇乱数列の決定方法
・6.タマゴ乱数列の決定方法

-1.ツール類

乱数調整に関連したツールをいくつか作ったのでよかったら使ってください。
・HGSS固定シンボル乱数調整
・タマゴ性格値調整
・裏ID判定

0.用語

とりあえず、性格値・個体値・裏ID・16進数・疑似乱数ぐらいは知っていること前提で。
実際の定義とか割と無視で思ったように使っているのでご容赦を。
SEED

前のSEEDによって求められ、次のSEEDを求める際使われる数値。

乱数

SEEDから計算して得られる、実際の計算に使われる値。
例えばSEEDの上位2バイト等。

乱数列

ゲーム中ではリアルタイムに計算されているとしても、疑似乱数は数列として扱う。
それだけで完結した数列を成すのは「乱数」ではなく「SEED」の方なので、SEED数列と言うべきかも。

SEEDの位置

次に乱数を求めるのに使われるSEEDの乱数列での位置。

乱数の消費

現在位置のSEEDから乱数を得て、SEEDの位置を乱数列の次の項にすること。

1.DPt,HGSSにおける乱数

DPtでは、野生ポケモンと遭遇(エンカウント)したときにその野生ポケモンの性格値・個体値が決められるのに乱数が使われる。
また、タマゴの性格値が決定される瞬間(育て屋爺が横を向く瞬間)にも、その性格値が決められるため乱数が使われる。
ただしこの2つの乱数は別の計算方法で数列化されており、前者を遭遇乱数列、後者をタマゴ乱数列と呼ぶことにする。
どちらもSEED1個は32bit。
遭遇乱数列は項の上位16bitが乱数として使われる。この実際使われる乱数の数列を{r[n]}とする。

2.遭遇乱数列の乱数消費契機

徘徊系の初期配置

犬→ラティの順に処理。
犬は最初はライコウ→エンテイだが、ライコウだけを倒して殿堂入りで復活することで入れ替わる。
次に使われる乱数をr[n]とすると
r[n+1]で位置を決定(エンテイ・ライコウの場合は16で割った余りがジョウト道路の昇順に対応、ラティアス・ラティオスの場合は25で割った余りがカントー道路の昇順に対応)
一個先の乱数を使うが消費は1。
ただし、再開するレポートを書いた時点での徘徊の位置と同じだった場合は再計算。
(徘徊しているポケモンの数+再計算回数)個消費

連れ歩きポケモンのメッセージ

連れ歩いているポケモンに話しかけることで消費する。
眠りの場合1回話しかける毎に4消費、
火傷の場合「やけどでくるしいようだ」で2、「がんばってついてきている」で4消費。
それ以外は不定個消費。

ポケギアの電話

電話をかけることで消費することがある。
判明しているところではトゲピーを見せた後のウツギ博士に電話で1個消費。
この際次に使われる乱数をr[n]とするとr[n+1]を3で割った余りによって内容が変わる。

また、再戦待機中でないたんぱんこぞうのゴロウに電話で2個消費。

128歩毎

(手持ちポケモン数)個消費

ぼうけんノート

ぼうけんノートで「○○を倒した」「○○を捕まえた」と書かれたページを「開く」度に2個消費。
メニューから使ったときの1ページ目でも消費しうるので注意。

エンカウント判定

草むら、洞窟、水上などポケモンが出現しうるマスで移動または方向転換をするとエンカウント判定が発生。
次に使われる乱数をr[n]とすると

・r[n]/0x290(百分率化)が謎の値より小さければ次へ。そうでないなら終了。1個消費
・r[n+1]/0x290がエンカウント率より小さければエンカウント処理へ。判定はここで終了。さらに1個消費

これがマス移動で1回、方向転換で1回行われるので、「向いていない方向へ移動」では2回行われる。
ただ、「出現マス」から「非出現マス」に移動するときは、移動のみでも方向転換移動でもこの処理は行われない。
スプレーを使っていても処理は行われる。

あまいミツ・あまいかおり

草むらで使うと1個、洞窟・水上で2個消費してエンカウント処理へ。
HGSSでは洞窟・水上でも1個消費
ポケモンが出現しうるマスでのみ消費する。

ずつき

2個消費してエンカウント処理へ

すごいつりざお※DPtでは未確認

釣り上げたとき3個消費してエンカウント処理へ、はやすぎたでは消費無し

エンカウント(シンクロ無し)

上記で「エンカウント処理へ」となった場合発生。
上記処理が終わったときの次の乱数をr[n]とすると

・r[n+1]/0xa3e(0〜24化)で性格を決定
・HGSSの場合下位r[n+1]%25で決定。
・m=n+2とし、
※r[m]を性格値の下位16bit、r[m+1]を性格値の上位16bitとして性格値生成
・性格が最初に決めたものと一致するまでmを2増やして再度※を実行
・r[m+2]が下位から5bitずつH,A,B、r[m+3]が下位から5bitずつS,C,Dの個体値となる。

戦闘中消費した乱数は戦闘終了後元の位置に戻り、1個消費。つまり、戦闘終了後の次の乱数はr[m+5]。
(※を行った回数×2+5)個消費

エンカウント(シンクロ有り)

次の乱数をr[n]とすると

・r[n+1]の上位1bitが0ならシンクロ成功、1なら失敗。失敗した場合はこの乱数が1個消費された状態でシンクロ無しエンカウント処理へ。
・HGSSの場合下位1bitで判定。
・m=n+2とし、
※r[m]を性格値の下位16bit、r[m+1]を性格値の上位16bitとして性格値生成
・性格がシンクロ持ちのものと一致するまでmを2増やして再度※を実行
・r[m+2]が下位から5bitずつH,A,B、r[m+3]が下位から5bitずつS,C,Dの個体値となる。

戦闘中消費した乱数は戦闘終了後元の位置に戻り、1個消費。つまり、戦闘終了後の次の乱数はr[m+5]。
(※を行った回数×2+5)個消費

エンカウント(徘徊系)

次の乱数をr[n]とすると

・r[n+1]を性格値の下位16bit、r[n+2]を性格値の上位16bitとして性格値生成
・r[n+3]を下位から5bitずつH,A,B、r[n+4]を下位から5bitずつS,C,Dとして個体値生成。

5個消費

NPC

主人公と同エリア上のNPCが移動したり方向転換したりするときに消費。
移動も方向転換もしないNPCは消費しない。

3.タマゴ乱数列の乱数消費契機

タマゴの性格値決定

1個消費。タマゴ乱数列のSEEDをEとすると、k[0~2]を32bitまで保持する変数として

・k[0] = (E/0x800) xor E
・k[1] = ((k[0]*0x80) and 0x9d2c5680) xor k[0]
・k[2] = ((k[1]*0x8000) and 0xefc60000) xor k[1]
・性格値 = (k[2]/0x40000) xor k[2]

小数点以下は出る度に切り捨て。
国際結婚(両親の出身国が違う)場合、上記性格値生成の後、性格値をPとして、Pで色違いにならないとき

P = P*0x6c078965+1とし、Pで色違いになるかチェック

が最大4回(途中で色違いになったら終了)実行される。
この処理では乱数は消費しない。

なつきチェッカー

ポケッチアプリでなつきチェッカーを開いたときと、なつきチェッカー中に下画面を連続で2回タッチしてポケモンが跳ねるエフェクトがあったときに(手持ちのポケモン数*2)個消費。
ただしタマゴは手持ちとしてカウントされない。

コイントス

ポケッチアプリでコイントスをしたとき(コインを投げるエフェクトがあったとき)に1個消費。

ポケギアの電話

電話をかけると消費することがある。
判明しているところではたんぱんこぞうのゴロウにかけると内容に関係なく2個消費。

4.共通初項(初期SEED)の決定方法

遭遇乱数列とタマゴ乱数列の初項は共通で、「つづきからはじめる」を押した瞬間に決定される。
この値を0xABCDEFとすると

AB:(秒+分+月*日) and 0xff
CD:時
EFGH:年-2000+ゲーム起動時からの経過時間
となる。年月日時分秒はDS内部時計の値で、起動時からの時間はA連打で進んだ場合0x256程度。

5.遭遇乱数列の決定方法

遭遇乱数列を{S1[n]}とすると、

S1[n+1] = S1[n] * 0x41c64e6d + 0x6073

となる。ただしS1[0]=初期SEEDで、33bit以上は切り捨て。

6.タマゴ乱数列の決定方法

624項の数列{t[n]}があり、t[0]から順に消費され、t[623]が消費されたとき{t[n]}が更新され、またt[0]に戻る。
t[n]の値を使う順に並べたものが、タマゴ乱数列{S2[n]}となる。
更新する処理がm回行われた後の{t[n]}を第mテーブルと呼ぶことにし、S2[(m-1)*624+n]は第mテーブルのt[n]と等しい。
最初に1回更新されるので、第0テーブルはSEEDとしては使われず第1テーブルの計算のみに使われる。

第0テーブルの決定
・t[0] = 初期SEED
・t[n] = ((t[n-1]の上位2bit) xor t[n-1])*0x6c078965 +n

n:1〜623であり小数点以下は出る度に切り捨て。

テーブルの更新(第m+1テーブルの決定)

k[0],k[1]を32bitまで保持する変数として

・k[0] = (t[A] and 0x80000000) or (t[B] and 0x7fffffff)
・k[1] = (k[0]/2) xor t[C]
・k[0]が奇数のときt[A] = k[1]xor0x9908b0df、偶数のときt[A] = k[1]

この処理がA,B,Cが以下の順として行われる。

・A=n、B=n+1、C=n+397 (n:0〜226)
・A=n、B=n+1、C=n-227 (n:227〜622)
・A=623、B=0、C=396
トップへ  次へ