ランダムな値を取得する
やりたいこと
1〜10のランダムな値を取得したい@cocos2d-x
1. rand() を使う
rand()
で、0からRAND_MAX(マクロで設定されてる)までの範囲の乱数値を得ることができるので、
それを割った余り(10で割っているのであまりは0〜9の範囲となる)を出し、それに1を足すことで1〜10となる
こう
static const int NUM_MAX = 10; int num = (rand() % NUM_MAX) + 1;
ただrand()
は、毎回同じ値の羅列を出してくるっぽい(疑似乱数)
割る値がコロコロ変わる場合はこいつだけでもよさそうだが、今回はNUM_MAX
が固定なのでちょっとダメ
2. srand() で初期化もする
なので、srand([ランダムな値])
で毎回初期化してから使うとよい
[ランダムな値]には現在時刻を入れるのがポピュラーっぽい(毎秒違う値になるので)
つまりこう
srand((unsigned int)time(NULL)); int num = (rand() % NUM_MAX) + 1;
3. arc4random() を使う
上記を1つにまとめた関数があり、それがarc4random()
かんたんべんり
int num = (arc4random() % NUM_MAX) + 1;
ただし、arc4random()
の戻り値はunsigned int
なので注意
intの上限である2147483647より大きい値が来ることがあり、それをintにcastするとオーバーフローして死ぬ(マイナス値になったりする)
上記のように、2147483647以下の値で割った余りとかの場合は、それ以下の値にしかならないので問題ないという認識
4. 乱数エンジンを使う
乱数エンジンを使う方法
C++11 から使える様子 あまりよくわかってない
std::random_device rnd; //乱数エンジンのシードにする乱数を生成 std::mt19937 mt(rnd()); //乱数エンジン(こいつはメルセンヌ・ツイスタというやつ、生成値はuint32_t)で乱数を生成する auto num = mt(); //生成された乱数
上記のmt()
のままでも使えるが、ディストリビューションというやつを使うと使い勝手がいい模様
たとえばランダムな角度を求めたい時
//今回は-89〜89度の範囲の角度が欲しいとする double degreeA = -89.0; double degreeB = 90.0; //degreeA以上degreeB未満のdouble値を返す設定のディストリビューションを作成 std::uniform_real_distribution<double> randDegree(degreeA, degreeB); //上記で作成したディストリビューションに乱数エンジンを渡すと、設定した範囲の乱数が取得できる double degree = randDegree(mt);
蛇足: 角度をラジアンに変換する
static const double PI = 3.141592653589793; //円周率 double radian = randDegree(mt) * PI / 180.0;
以上
参考
ロベールのC++教室 - 第75章 乱数 -
【cocos2dx】乱数を生成し、ランダムに値を取り出す方法 | albatrus.com
乱数の使用
C言語 「角度からラジアンに変換」 と 「ラジアンから角度に変換」 | 勇躍のゴミ箱