乱数の生成
乱数を生成するのがrand関数
RAND_MAX:rand関数で生成できる最大値
rand():0~RAND_MAXの範囲でランダムな値を戻り値とする関数
プログラム例
#include <iostream>
using namespace std;
int main()
{
int retry; // もう一度?
cout << "この処理系では0~" << RAND_MAX << "の乱数が生成できます。\n";
do {
cout << "\n乱数" << rand() << "を生成しました。\n";
cout << "もう一度? … (0)いいえ (1)はい:";
cin >> retry;
} while (retry == 1);
return (0);
}
—実行例
この処理系では0~32767の乱数が生成できます。
乱数41を生成しました。
もう一度? … (0)いいえ (1)はい:1
乱数18467を生成しました。
もう一度? … (0)いいえ (1)はい:1
乱数6334を生成しました。
もう一度? … (0)いいえ (1)はい:1
乱数26500を生成しました。
もう一度? … (0)いいえ (1)はい:0
繰り返すたびに、ランダムな値が表示されていることが分かります。ただ、何度プログラムを動かしても同じランダムな値が表示されます。
プログラムを動かすたびに違う乱数とする
乱数の種
乱数は、「種」と呼ばれる基準値に演算を施して作られます。
プログラム実行のたびに同じ乱数が生成されるのは「定数1という種がrand関数に埋め込まれている」からです。異なる乱数を生成するには、種の値を変えなければなりません。それを行うのがsrand関数です。
srand関数:乱数の種を引数とする
srand関数は、プログラムの最初に1回呼びます。(何度も呼ぶものではない)
ここで、乱数の種を定数としてしまうと毎回同じ値となってしまうため、プログラムを動かすたびに違う値になるように設定します。そこでよく使われるのは、現在時刻を取得するtime関数を使ってプログラムを起動するたびに違う値を乱数の種とする方法です。
time関数:引数にNULLを設定すると、1970年 1月 1日の00:00:00 から現在までの経過時間を秒単位で戻り値としてくれる
time関数を使うためには、<time.h>をインクルードする必要があります。
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
int retry; // もう一度?
srand((unsigned int)time(NULL)); // 乱数の種を初期化(プログラムの先頭で1回のみ)
cout << "この処理系では0~" << RAND_MAX << "の乱数が生成できます。\n";
do {
cout << "\n乱数" << rand() << "を生成しました。\n";
cout << "もう一度? … (0)いいえ (1)はい:";
cin >> retry;
} while (retry == 1);
return (0);
}
サイコロプログラム
0~RAND_MAX までのランダムな値を出力するrand()関数を使って、指定された範囲内でランダムな値を出すようにするには、割ったあまりを使うとよい。
- rand() % 10 : 0~9の範囲でランダムな値
- rand() % 21 + 10 :10~30の範囲でランダムな値
rand() % (最大値-最小値+1) + 最小値 : これで自由に範囲を決めることができる。
サイコロのように1~6のランダムな値を出す
#include <iostream>
#include <time.h>
using namespace std;
// サイコロの目を出す関数
int dice(){
// 6で割った余り(0~5)に1を足す
return rand() % 6 + 1;
}
int main()
{
int retry; // もう一度?
srand((unsigned int)time(NULL)); // 乱数の種を初期化(プログラムの先頭で1回のみ)
cout << "サイコロを振ります。\n";
do {
cout << "\nサイコロの目は" << dice() << "です。\n";
cout << "もう一度? … (0)いいえ (1)はい:";
cin >> retry;
} while (retry == 1);
return (0);
}