ランダムな数値を取得するときはNextメソッド等を使用します。以下はNextメソッドの単純な使用例です。この例ではNextメソッドに最小値と最大値を指定しています。この場合Nextメソッドの戻り値は最小値以上、最大値未満の整数になります。Randomクラスはこの他の方法でランダムな数値を生成することもできます。その方法は少し後で説明します。
■リスト1:Randomクラスを使用する際は次の指針を念頭においてください。
- 乱数が必要となるたびにRandomクラスのインスタンスを作成するのではなく、1回だけ生成したRandomクラスのインスタンスを何回も使うようにしてください。
- Randomクラスのインスタンスを作成する場合はコンスタクラに毎回同じ引数が渡らないようにしてください。そのためには引数なしのコンストラクタを渡すか、時刻などその都度変わる値をコンストラクタに指定します。
- Randomクラスが使用する擬似乱数発生のアルゴリズムは公開されているため、どのような乱数が発生するのか予測可能な場合があります。セキュリティ上重要なな暗号化などに使用する乱数の生成にはRandomクラスではなくRNGCryptoServiceProviderクラスを使用してください。
このようにしなかった場合、生成される数値はランダムでなかったり、予測可能なものとなってしまいます。Randomクラスが生成するランダムな数は確率精度が劣るために厳密には数学上の「乱数」ではありませんが、この精度の違いは無視しても構わないくらい小さいので「乱数」として扱うことができます。
2.コンストラクタ
コンストラクタは次の2つです。
コンストラクタの引数 | 説明 |
(なし) | インスタンスを作成したときの時刻を利用してランダムな数を生成します。同じ時刻にインスタンスを作成すると同じ値を生成します。 |
Integer | 引数を利用してランダムな数を生成します。同じ引数を渡すと同じ値を生成します。 |
■表1
3.ランダムな数値の生成規則
Randomクラスはインスタンス化されたときに既にどのようなランダムな数値を発生させるか決定しています。そのため、同じ方法でRandomクラスをインスタンス化するといつも同じ数値を返すようになります。
たとえば、次のコードのようにRandomクラスのコンストラクタに 0 を指定すると、Nextメソッドは必ず 8, 9, 8, 6, 3, 6, 10, 5, 10, 3, 3, … の順で数値を生成します。
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random(0)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
TextBox1.Text = MyRandom.Next(1, 11)
End Sub
■リスト2:このため、はじめに書いたように、Randomクラスのインスタンスを作成する場合は固定で数値を指定するのではなく、時刻のようにその都度変わる値を指定するか、引数なしのコンストラクタを使用します。
なお、このようにランダムな数列を発生させるために渡す初期値のことを「乱数シード」または単に「シード」と呼びます。「シード」とは英語のseed、つまり種のことです。
さて、引数なしのコンストラクタを使用した場合にランダムな数値が必要になるたびにインスタンスを作成すると、予期せぬ数値を生成する場合があります。
次の例では、TextBox1とTextBox2にはかなり高い確率で同じ値が表示されます。
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom1 As New Random
TextBox1.Text = MyRandom1.Next(1, 11)
Dim MyRandom2 As New Random
TextBox2.Text = MyRandom2.Next(1, 11)
■リスト3:引数なしのコンストラクタを使用した場合、時刻を元にランダムな数列を生成するので、このように短い間隔でインスタンスを作成した場合は同じ時刻が使用されて同じ数列が生成されてしまいます。これらの問題を回避するためにRandomクラスはその都度インスタンスを作成するのではなく、1回だけ作成したインスタンスを何度も使うようにします。
次の例ではTextBox1とTextBox2には高い確率で異なる数値が表示されます。
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
TextBox1.Text = MyRandom.Next(1, 11)
TextBox2.Text = MyRandom.Next(1, 11)
End Sub
■リスト4:ところで、気にしている方が多いようなのでランダムな数値の予測可能性について少し触れておきますが、実際のゲーム等に使用する分には十分な精度でランダムな数値が生成されますので通常は気にする必要はありません。
4.ランダムな数値の取得方法
Randomクラスを使うといくつかの方法でランダムな数値を取得することができます。それぞれの使用例も合わせてまとめます。
生成されるランダムな数値 | 生成方法 |
0~2147483647の範囲でランダムな整数を取得する。 | Nextメソッドを引数なしで使用します。 |
指定した最大値未満で0以上のランダムな整数を取得する。 | 最大値を指定してNextメソッドを使用します。 |
指定した範囲内でランダムな整数を取得する。 | 最小値と最大値を指定してNextメソッドを使用します。 |
0~255の範囲でランダムなの整数の数列を取得する。 | NextBytesメソッドを使用します。 |
0以上1未満のランダムな小数を取得する。 | NextDoubleメソッドを使用します。 |
■表2
使用例1:0~2147483647の範囲でランダムな整数を取得する
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
TextBox1.Text = MyRandom.Next
■リスト5:使用例2:指定した最大値未満で0以上のランダムな整数を取得する
この例では0~100までのランダムな整数を取得します。Nextメソッドの引数は101となっていることに注意してください。
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
TextBox1.Text = MyRandom.Next(101)
■リスト6:使用例3:指定した範囲内でランダムな整数を取得する
この例では1~12までのランダムな整数を取得します。Nextメソッドの第2引数が13となっていることに注意してください。
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
TextBox1.Text = MyRandom.Next(1, 13)
■リスト7:使用例4:0~255の範囲でランダムな整数の数列を取得する
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
Dim RandomBytes(99) As Byte
MyRandom.NextBytes(RandomBytes)
For Each b As Byte In RandomBytes
ListBox1.Items.Add(b)
Next
■リスト8:使用例5:0以上1未満のランダムな小数を取得する
[VB2002][VB2003][VB2005][VB2008][VB2010][VB2012][VB2013][VB2015][VB2017]
Dim MyRandom As New Random
TextBox1.Text = MyRandom.NextDouble
■リスト9:5.Randomクラス以外のランダムな値
Randomクラス以外にもランダムな値を発生させるための機能があります。1つははじめにも少し言及したRNGCryptoServiceProviderクラスを使う方法です。このクラスは暗号乱数ジェネレータを使用してランダムな値の数列を生成します。
もう1つの方法としてVBのRnd関数を呼び出してランダムな値を生成することもできます。Rnd関数は0以上1未満のランダムな小数を返します。Randomizeステートメント使用するとRnd関数が生成する乱数に新しいシードを引き渡すことができます。
資料:RandomクラスのPublicメンバ
名前 | 由来 | 読み方 | 機能 |
Equals | Object | イコールズ | |
GetHashCode | Object | ゲットハッシュコード | |
GetType | Object | ゲットタイプ | |
Next | | ネクスト | ランダムな整数を生成 |
NextBytes | | ネクストバイツ | ランダムな数列を生成 |
NextDouble | | ネクストダブル | ランダムな小数を生成 |
ReferenceEquals | Object | リファレンスイコールズ | |
ToString | Object | トゥーストリング | クラスの完全限定名を返す |
■表3