VB6で乱数を

乱数を発生させる/乱数の初期化/履歴…>ランダムセレクト

乱数を発生させる

記念すべきプログラミングコーナー第1回。
まずはじめに紹介するのは乱数の発生についてです。

とりあえず任意の範囲の乱数を発生させてみます。
0以上1未満の乱数を発生させるためには Rnd 関数を使います。
つまり、0≦Rnd<1 ということです。
ここで、各辺に正の数nをかけると、0≦n*Rnd<n となり、0以上n未満の乱数が得られます。
これに最小値 Min を足すと、Min≦n*Rnd+Min<n+Min
さらに、n=Max-Min とすると、Min≦(Max-Min)*Rnd+Min<Max
これでめでたく Min 以上 Max 未満の乱数
(Max-Min)*Rnd+Min
を作ることができました。

しかし、こうやって得られた乱数は小数なので、残念ながらそのまま使うことはあまりありません。
だから、今度は Min 以上 Max 以下の整数の乱数を作ります。
そのためには小数を整数に変換する Int 関数を使います。
こうしてできた乱数 Int((Max-Min)*Rnd)+Min はまだ使えません。
なぜなら、この時 Min≦Int((Max-Min)*Rnd)+Min<Max で、
Int((Max-Min)*Rnd)+Min が整数だから、
Min≦Int((Max-Min)*Rnd)+Min≦Max-1
つまり、Min 以上 Max-1 以下の乱数しか得られないわけです。
そこで、Max を Max+1 に置き換えます。
Min≦Int((Max-Min+1)*Rnd)+Min≦Max

これで、Min 以上 Max 以下の乱数
Int((Max-Min+1)*Rnd)+Min
を作ることができました。

↑RPGやろうさんの指摘によりInt((Max-Min+1)*Rnd)から訂正しました。

サンプル(1.58kilobyte)

乱数の初期化

ここでいっておかなければならないことがあります。
それは、Rnd 関数は本当の意味の乱数など返さないということです。
つまり、Rnd関数が返すのは本当の乱数ではなくて、擬似乱数に過ぎないということです。

ここでRnd関数について詳しく説明しますが、知っている方は読みとばしてくださってかまいません。
まずRnd関数は、「関数」というからにはしっかりと関数の性質を持っています。
関数とは、ある数がただ一つに定まるとただ一つの値が決まるというものです。
つまり、Rnd関数も当然何かの数にしたがってただ一つの値をとるというわけです。

さて、ではその何かの数とは一体どんな数なのでしょうか。

普通Rnd関数を使う前にはRandomizeを使いますね。
Randomizeは乱数の初期シード値を決める関数です。
だから、Rnd関数はシード値の関数といえそうです。

また、Rnd関数を何度か連続して使うと毎回違った値をとりますね。
ということは、Rnd関数は自身の使われた回数の関数でもあるようです(実際は少し違いますが)。

理屈はここまでにしておいて…
では、ここから本題です。

Rnd関数はシード値と使用回数の関数であるわけですから、Randomizeを使う際にシード値を保存しておき、使用回数を0回に戻してやれば再現性のある乱数を作ることができるのです。

でもRandomizeのシード値なんてわからないじゃないかとか、使用回数を0回に戻すなんて不可能だ、といわれそうですね。

それがわからなければこんなことをやっていないわけなので、方法を書いておきます。

シード値を知る
Randomizeは引数を省略すると、

Randomize Timer()

と解釈されます。
だから、Randomizeを使うときに

Dim seed As Single
seed = Timer()
Randomize seed

としておけば、seedにシード値が入ります。

使用回数を0回に戻す
Rnd -1

で実現できます。
ただし、同時にシード値を変更してしまうので
Randomizeを使う直前に使ってください。

これはゲームのリプレイ機能などに使えます。

サンプル(1.85kilobyte)

更新履歴

02/03/27乱数の初期化
01/10/11乱数を発生させる