プラチナループタマゴ版 platroop 解説前編 乱数の仕組み
思いつきで真面目に乱数の話でもしてみる。暇だったら後編 実用的方法について書くかも
性格値、個体値、裏ID、16進数、疑似乱数ぐらいは知ってること前提で。
適当に思いついた用語連発なので使い方間違ってたら言って
0.用語の確認
とりあえずここでは、疑似乱数は(ゲーム中ではリアルタイムに次の項が計算されているとしても)初項が決まれば得られる無限に続く数列とする。(乱数列)
乱数列の決定に使われる値をseedと呼ぶ。(seedは大抵既に決定された乱数列の値である)
ゲームのメモリには「次に使われる乱数の値」が記録されているアドレスがあり、この「乱数の値が乱数列でのn項分先の値になること」を「乱数がn個消費される」と呼ぶ。
1.DPtにおける乱数
DPtでは、野生ポケモンと遭遇(エンカウント)したときにその野生ポケモンの性格値・個体値が決められるのに乱数が使われる。
また、タマゴの性格値が決定される瞬間(爺さんが横を向く瞬間)にも、その性格値が決められるため乱数が使われる。
ただしこの2つの乱数は別の計算方法で数列化されており、前者を遭遇乱数列({r[n]})、後者をタマゴ乱数列({e[n]})と呼ぶことにする。
どちらも乱数1個は32bit。
2.乱数の消費契機
それぞれの乱数列について、現在判明している乱数消費契機は以下の通り。
遭遇乱数列
- 128歩毎
(手持ちポケモン数)個消費
- 「ぼうけんノート」で「○○を倒した」「○○を捕まえた」と書かれているページを開く
2個消費
戦闘中に消費した乱数は戦闘終了後、相手ポケモンの性格値・個体値が決定された後の状態まで戻ると思われる。
その時点での乱数を乱数列での第n項とすると出現するポケモンの性格・性格値・個体値は
r[n]の上位2バイト/0xa3eで性格を決定
m=n+1
※r[m]の上位16bitが性格値の下位16bit、r[m+1]の上位16bitで仮性格値計算
このとき最初に決めた性格と一致しなかったらmを+2して※を繰り返し
r[n+2]の上位16bitが下位から5bitずつHAB、r[n+3]の上位16bitが下位から5bitずつSCDとなる。
- ポケモンが出現しうるマスであまいかおり・あまいミツ
草むらで使った場合1個、洞窟・水上で使った場合2個消費
- ポケモンが出現しうるマスで移動・方向転換
その時点での乱数を乱数列での第n項とすると
r[n]の上位16bit/0x290が謎の値より小さければ次へ。そうでないなら終了。1個消費
r[n+1]の上位16bit/0x290がエンカウント率より小さければポケモン出現。ここまでで2個消費
これが移動で1回、方向転換したらさらに1回行われる。
- NPCの方向転換・移動
詳細不明。方向転換・移動可能性無しのNPCは消費しない。
今のところ信頼性が高いのは128歩毎とぼうけんノートによる消費
3.乱数決定方法
どちらの乱数列も、初項が決まればその後の項は無限に決まる。ただしこの2数列には決定方法に違いがある。
初項r[0],e[0]は同じ値だが、r[n+1]は常に前の項r[n]のみがseedとなるのに対し、e[n]は624項単位で、624項の値がseedとなり次の624項が決まる。
初項r[0]、e[0](両乱数列共通)
セーブデータの画面で「つづきからはじめる」を押した瞬間に決定される。値を0xABCDEFとすると
- AB:(秒+分+月*日)&0xff
- CD:時間(0x00~0x18)
- EFGH:年-2000
がまず代入され、最後にゲーム起動からの経過時間による値を足す。Aボタン連打でつづきからはじめるを押した場合、0x256程度。
ここで使われる年月日時分秒は決定される瞬間のDS内部時計から取得されるもの。
遭遇乱数列
r[n+1] = r[n] * 0x41c64e6d + 6073
(但し33bit以上は保持されない)
タマゴ乱数列
624項の数列{t[n]}があり、t[0]から順に消費され、t[623]が消費されたときt[0]〜t[623]を使いt[0]〜t[623]を更新する。
次の乱数はt[0]に戻り、これを使う順に並べたものがタマゴ乱数列である。
更新する処理がm回行われたときの{t[n]}を第mテーブルと呼び、第mテーブルのt[n]=e[(m-1)*624+n]である。
- 第0テーブルの決定(第1テーブルの決定にのみ使われる)
t[0] = e[0](共通初項)
t[n] = ((t[n-1]>>30)^t[n-1])*0x6c078965+n
(n:1〜623)
- テーブル更新(第m+1テーブル決定)
A,B,Cをt[n]のある項とする。
k[0]・k[1]を32bitまで保持する変数として
k[0] = (A&0x80000000)|(B&0x7fffffff)
k[1] = (k[0]>>1)^C
k[0]の下位1bitが1(k[0]が奇数)のときA = k[1]^0x9908b0df
奇数ではないときA=k[1]
この処理はABCを以下として順に行われる
・n=0〜226としてA=t[n]、B=t[n+1]、C=t[n+397]
・n=227〜622としてA=t[n]、B=t[n+1]、C=t[n-227]
・A=t[623]、B=t[0]、C=t[396]
タマゴ乱数列からの性格値生成
使う乱数をe[n]としたとき
k[0][1][2]を32bitまで保持する変数として
k[0] = (e[n]>>11)^e[n]
k[1] = ((k[0]<<7)&0x9d2c5680)^k[0]
k[2] = ((k[1]<<15)&0xefc60000)^k[1]
性格値 = (k[2]>>18)^k[2]
国際結婚時の処理
両親の国籍が違った場合、通常の性格値生成による性格値をPとして
P = P*0x6c078965+1
Pの性格値で色違いになるかチェック
色違いだったら処理を終了
の3つが最大4回実行される。(最初の性格値は必ず変更される)