【C#, VB.NET】乱数の生成

#概要
ここではC#とVB.NETでランダムな数値を生成する方法を紹介します。
C#／VB.NETは簡単に乱数を生成できます！

乱数はよく使うので、覚えておくと便利です。

#開発環境
IDE: Visual Studio 2015
OS : Windows 10

※自分の環境です

#Randomクラス
C#／VB.NETで乱数を生成するには**Randomクラス**を使用します。
まずはnew演算子でRandomオブジェクトを作成します。
オブジェクトの作成は変数宣言とほぼ同じです。

```C#:rnd.cs
Random rnd = new Random();
```
```VB:rnd.vb
Dim rnd As New Random()
' 以下のような書き方でも可
' Dim rnd As Random = New Random()
```

はい、これだけで乱数を生成する準備は完了です！**ね、簡単でしょ？**
ただし、C#では以下のようにSystemが明示的にインポートされていないと使えないので注意しましょう。ですが、ソースを新規作成した時に大体は自動的に付加されるのであまり気にしなくてもよいでしょう。

```C#:rnd.cs
using System;
```

#Nextメソッド
先ほど作成したRandomオブジェクトの**Nextメソッド**を使用することでランダムな数値を得ることが出来ます。
RandomオブジェクトにはNextメソッドが3つ定義されていますが、その中でも個人的によく使うものを紹介します。

#Next(int minValue, int maxValue)メソッド
よく使うメソッドなので是非覚えましょう。
これを呼び出すとminValueからmaxValueまでの範囲でランダムな整数値を取得できます。
**ただし、maxValueは含まれないので注意しましょう。**
つまり、**minValue以上、maxValue未満**のint型の整数値が返ることになります。
呼び出し方法の例は以下のようになります。

```C#:rnd.cs
Random rnd = new Random();    // Randomオブジェクトの作成
rnd.Next(1, 10);  //1以上10未満の値がランダムに出力
```
```VB:rnd.vb
Dim rnd As New Random()    ' Randomオブジェクトの作成
rnd.Next(1, 10)   '1以上10未満の値がランダムに出力
```

#使用例
0から50までの整数値をランダムに取得し、取得した整数値を表示してそれが25以上なら"A"、そうでなければ"B"と表示するコードです。実行結果は、実行する毎に変化します。

```C#:sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestCS
{
    class Program
    {
        static void Main(string[] args)
        {

            Random rnd = new Random();      // Randomオブジェクトを作成

            int x = rnd.Next(0, 50);        // 0から50までの値をランダムに取得

            Console.WriteLine(x.ToString());
            if (x >= 25)
            {
                Console.WriteLine("A");
            }
            else
            {
                Console.WriteLine("B");
            }

            Console.ReadLine();
        }
    }
}
```
```VB:Sample.vb
Module Module1

    Sub Main()

        Dim rnd As New Random()     ' Randomオブジェクトの作成

        Dim x As Integer = rnd.Next(0, 50)   ' 0から50までの値をランダムに取得

        Console.WriteLine(x)
        If x >= 25 Then
            Console.WriteLine("A")
        Else
            Console.WriteLine("B")
        End If

        Console.ReadLine()
    End Sub
End Module
```
Randomクラスという存在を知っていれば乱数は超簡単に生成できます！！

ちなみに、ランダムな0以上1.0未満の実数値を取得したい場合は**NextDoubleメソッド**で取得できます。

#Randomクラスのもう1つのコンストラクタ
コンストラクタはオブジェクトを作成する時に呼ばれます。詳しいことは別の記事で載せる予定です。
Randomクラスのコンストラクタには引数無しのタイプと整数値を引数として渡すタイプの2つがあります。

・Random()
・Random(int seed)

以下のソースは下側のコンストラクタでRandomオブジェクトを作成しています。
これを実行するとランダムな数値は得られていますが、実行結果は何回やっても同じになります。

```C#:seedsRnd.cs
Random rnd = new Random(3);      // Randomオブジェクトを作成

for (int i = 0; i < 5; i++)
    Console.WriteLine(rnd.Next(0,10));

Console.ReadLine();
```

ゲームのリプレイ機能とかで使えそうですね。

#注意点
以前、私がゲームを作ってた時に引っ掛かったので一応書いておきます。
Randomオブジェクトを作成するとき、場所に注意が必要です。
例えば、以下のようなソースがあったとします。

```C#:Sample2.cs
for (int i = 0; i < 10; i++)
{
    Random rnd = new Random();
    Console.WriteLine(rnd.Next(0, 10));
}
Console.ReadLine();
```
``` VB:Sample2.vb
For i As Integer = 0 To 9
    Dim rnd As New Random()
    Console.WriteLine(rnd.Next(0, 10))
Next
Console.ReadLine()
```
以上のソースを実行すると結果はどうなるでしょうか？

0から10までのランダムな値が10個出てくるだろう……

**……と、**思っていた自分がいました。

実際はそうではなく、**同じ数値が連続で出力される**現象が起こります。
~~そのせいで昔、どこがおかしいのか分からなくてずっと悩んでいた時がありました。~~

対策方法としては、**宣言文をループの外に出す**というのが良いでしょう。
以下は上記のソースを修正したソースになります。

```C#:seedsRnd.cs
Random rnd = new Random(3);      // Randomオブジェクトを作成

for (int i = 0; i < 5; i++)
    Console.WriteLine(rnd.Next(0,10));

Console.ReadLine();
```

ゲームのリプレイ機能とかで使えそうですね。

#注意点
以前、私がゲームを作ってた時に引っ掛かったので一応書いておきます。
Randomオブジェクトを作成するとき、場所に注意が必要です。
例えば、以下のようなソースがあったとします。

```C#:Sample2.cs
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(rnd.Next(0, 10));
}
Console.ReadLine();
```
``` VB:Sample2.vb
Dim rnd As New Random()
For i As Integer = 0 To 9
    Console.WriteLine(rnd.Next(0, 10))
Next
Console.ReadLine()
```

このようにすれば、同じ数値が連続して出てくることは無くなります。~~低確率で連続することはあります。~~

#まとめ
・C#／VBで乱数を生成したいときは**Random**オブジェクトを作成して準備する
・実際に生成する時は、Randomオブジェクトの**Next**メソッドを呼び出す。

#参考文献
[Random クラス(Microsoft Docs)](https://docs.microsoft.com/ja-jp/dotnet/api/system.random?view=netcore-3.1)