グローバルじゃない乱数生成(線形合同法)
良質な乱数でなく、ゲームとかの演出その他程度に手軽に使う用の乱数生成用クラス
#include <iostream> using namespace std; class RandomGenerator{ static const long int A = 22695477; static const long int C = 2531011; private: long int x; public: // 初期シードを引数に取るコンストラクタ(srand(firstseed)相当) inline RandomGenerator(long int firstseed=1){ this->srand(firstseed); } inline void srand(long int firstseed=1){ x = firstseed; // 線形合同法は生成開始直後は凄く偏るので1000回程度読み飛ばす for(size_t i=0; i<1000; ++i) (*this)(); } // ANSI-Cで保障されたintの最大値を初期値として、欲しい乱数の上限を設定できる inline int operator()(int rand_max = 32767) { rand_max++; x=x*A+C; return (int)((x>>16)&32767)%rand_max; } }; int main(){ int seed = 12345; // 初期シードを引数にして乱数生成インスタンスを作成 RandomGenerator rand(seed); cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << "--------" << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << "--------" << endl; // さっきの初期シードで再初期化して、同じ乱数を再現する rand.srand(seed); cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << "--------" << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << rand(10) << endl; cout << "--------" << endl; return 0; }
出力結果
21564 24754 30518 2323 -------- 10 2 5 8 -------- 21564 24754 30518 2323 -------- 10 2 5 8 --------
まあVS2010の標準ライブラリ使えって話もあるんだけど、2008かつ手軽に使える用のシロモノ。
2008までの標準ライブラリの乱数はグローバルなんでイマイチ使い勝手が悪い。