キャリー付き乗算
TUSBではキャリー付き乗算(multiply-with-carry, MWC)を用いて乱数の取得を行っている。
キャリー付き乗算 (英: multiply-with-carry, MWC) は、George Marsagliaにより開発された整数疑似乱数生成用の手法である。乱数種には2〜数千の値を必要とする。MWC の主な長所は、単純な整数演算からなっており非常に高速に動作するという点と、\(2^{60\dots 2000000}\) という非常に長周期であるという点である。
(キャリー付き乗算-Wikipediaより引用)
細かい理論については置いておき、TUSB内でどのように計算が行われているかというと、以下の式を繰り返し計算して乱数列を得ている。
\[x_n = \begin{cases} (ax_{n-1}+c_{n-1})\mod b & (n>1)\\ GameTime\mod b & (n=1) \end{cases}\\ c_n = \begin{cases} \lfloor \frac{ax_{n-1}+c_{n-1}}{b}\rfloor & (n>1)\\ GameTime\mod b & (n=1) \end{cases}\]\(x_n\)が乱数列で、\(c_n\)がキャリーとなっている。
但し、
である。\(x_n\)を特定の値との剰余を求める事により、ある範囲の乱数を得る。
初項\(x_1,c_1\)
初項\(x_1,c_1\)はどちらも\(x_1,c_1 = GameTime\mod b\)である。
#GameTime
のGlobal
(以降、#GameTime
)はプレイヤーが初めてTUSBにログインしたとき(具体的にはチームに属していないプレイヤーが存在するとき)、その時のワールドが作られてからの時間を記録する。ソロプレイであれば、その時一回限りの更新であり、マルチプレイであれば、新しいプレイヤーがログインするたびに#GameTime
は更新される。
#GameTime
は基本的に7171674となるが、ラグによってはこれとは異なる値になるかもしれない。あくまで参考までに。乱数の更新
乱数の更新は以下の2つの条件に該当するとき、行われる。
- プレイヤーが初めてTUSBにログインしたとき
UpdateRandom
が付与されたプレイヤーが存在するとき
乱数の使い方
TUSBの二次創作等で乱数を使用する方法について記す。
- プレイヤーの
RndMWC
(これが\(x_n\))の値をRandom
等の一時変数に代入 - プレイヤーに
UpdateRandom
を付与 - 取得したい値の範囲(0 ~ 9など)に対応した値(0 ~ 9であれば10)で
Random
との剰余を計算する
RndMWC
の値を直接変更する行為は避けた方が良いだろう。乱数の特定について
ここでは、乱数が特定することが可能であるか考える。
まずTUSBでは前述したように乱数の更新のほとんどは、UpdateRandom
によって行われる。これは数はあるが特定は容易である。次に、プレイヤーが初めてTUSBにログインしたときの#GameTime
の特定だが、ソロプレイでは可能であるかもしれない。しかし、マルチプレイでは2人目以降のプレイヤーの初ログイン時間の特定はコマンドを使わない限り不可能である。
結論としては、ソロプレイならば#GameTime
が一意に定まり、UpdateRandom
を付与されるタイミングをすべて把握することができるのなら乱数の特定が可能となり、マルチプレイでははぼ不可能と考えられる。
まぁ、できても人力TAS?に近い状態なので現実的ではないだろう。
UpdateRandomが付与されるタイミング一覧
後々、書きます。