この頁では乱数に関する全般的な仕様、又は乱数調整の方法について解説する。
用語
この頁の内容を理解するための最低限の用語を解説する。
乱数
簡単に言うと、予測できない数字、規則性の無い数字。または数字列。
ゲームなどで使用する乱数は計算によって生成されており、
一見無秩序な数字に見えるが予測することが可能なので、厳密には擬似乱数という。
乱数列が進むことを「乱数を消費する」「乱数が回る」と表記されることが多い。
乱数生成器(RNG)
乱数を生成する機器・計算。
エアライドでは線形合同法(LCG)という疑似乱数の生成式が使用されている。
他には、線形帰還シフトレジスタ(LFSR)、メルセンヌ・ツイスタ(MT)、Xoroshiroなど
様々な種類が存在する。
16進数、2進数
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,12,13…
と1桁につき16数えると桁が上がる数字が16進数。
0,1,10,11,100,101,110,111,1000,1001,1010,1011…
と1桁につき2数えると桁が上がる数字が2進数。
普段我々が使っている数字は10進数である。
例えば10進数の999を16進数で表記すると3E7、
2進数で表記すると1111100111になる。
16進数であることを明示するために、0x3E7, 3E7H,
2進数であることを明示するために、0b111110011, 111110011B,
等の表記をするのが一般的である。
bit(ビット)
コンピュータにおける最小単位。
1と0で表せる2種類の情報であり、2進数での1桁。
また、8bitのことを1byte(バイト)といい、1byteは256種類の情報を表せる。
乱数生成式
カービィのエアライドにおける乱数は以下の式によって生成される。
Rn+1 = Rn * 214013 + 2531011 mod 4294967296
前回の乱数値に214013を掛け、2531011を足し、4294967296で割った余りを
次の乱数値とするというものである。
この乱数は0から4294967295の範囲を取り、4294967296消費でループする。
プログラム風に書くと、
R = (R * 0x343FD + 0x269EC3) & 0xFFFFFFFF;
ゲーム内において乱数値は0x805D7778のアドレスに格納されている。
乱数による結果生成
実際にこの乱数からどのように結果が生成されているか解説する。
基本的には乱数を消費し、新しく生成された乱数値から何らかの計算を行い結果を生成する。
ゼロヨンアタック1
ゼロヨンアタック1では、コースのロード時に
8つあるオブジェクトとスタート位置が乱数により決定されている。(9消費)
1-5回目の消費で1-5つ目のオブジェクトの種類と位置が決定される。
乱数を2^30で除算した結果(切り捨て)が
0なら左DP、1なら右DP、2なら左ルーレット、3なら右ルーレット となる。
6回目の消費で6つ目のオブジェクトの位置が決定されるが、左DPで確定。(設定ミス?)
7-8回目の消費で7-8つ目のオブジェクトの位置が決定される。
乱数を2^31で除算した結果(切り捨て)が
0なら左DP、1なら右DP となる
9回目の消費で開始位置が決定される。
乱数を2^30で除算した結果(切り捨て)が
0なら左、1なら左中、2なら右中、3なら右 となる。
プログラム的に言うと2^nでの除算はn bit右シフトと同義。
例えば、直前の乱数値(R0)が0x11111111だった場合は以下のような結果になる。
乱数値 | 計算 | 結果 | |
R0 | 0x11111111 | ||
R1 | 0x88AEEF90 | /2^30 = 2 | 左ルーレット |
R2 | 0xAC6C1013 | /2^30 = 2 | 左ルーレット |
R3 | 0xDF607A8A | /2^30 = 3 | 右ルーレット |
R4 | 0x722FD725 | /2^30 = 1 | 右DP |
R5 | 0xE42BED54 | /2^30 = 3 | 右ルーレット |
R6 | 0xC6A926C7 | 左DP | |
R7 | 0x0ECD066E | /2^31 = 0 | 左DP |
R8 | 0x5CBEC379 | /2^31 = 0 | 左DP |
R9 | 0xE0417858 | /2^30 = 3 | 開始位置:右 |
ポイントストライク
シティトライアル
乱数調整
ここまでの情報を踏まえ、実際にどのように狙った現象をゲーム内で引き起こすか解説する。