[M1 Mac, Monterey 12.6.3, clang 13.0.0, SDL 2.26.2, ChatGPT Plus, NO IDE]
テトリスC++版ではMacOSのstdlib.hにあるrand関数をこれまで使っていましたが、偏りがひどく乱数生成器として用を成さないため、ChatGPTに教えてもらった<random>ヘッダに変更しました。
#include <random>
int TetroTypeGenerator()
{
int tetroType;
if (GeneratorCount == 0){
arr = {0, 1, 2, 3, 4, 5, 6};
}
while(1){
// 乱数生成器を初期化する
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
// 0から6の7つの整数から一つランダムに選択する
std::uniform_int_distribution<int> dist(0, 6);
int tetroType = dist(engine);
// tetroType = rand() % kNumTetrominoTypes; // 偏りがひどいので不採用
cout << "tetroType生成器: " << tetroType << endl;
if (arr.size() == 0){
arr = {0, 1, 2, 3, 4, 5, 6};
cout << "テトロミノ配列が空になったのでリセットしました" << endl;
} else if (arr.size() == 1){
tetroType = arr.front();
arr = {};
cout << "tetroType残り1: " << to_string(tetroType) << endl;
GetScoreAndDate();
makeRanking();
GeneratorCount++;
return tetroType;
}
for (auto it = arr.begin(); it != arr.end(); ) {
if (*it == tetroType) {
it = arr.erase(it);
cout << "tetroType: " << to_string(tetroType) << endl;
GetScoreAndDate();
makeRanking();
GeneratorCount++;
return tetroType;
} else {
it++;
}
}
}
}
ChatGPT
Q: MacOSのstdlib.hにあるrand関数の生成する乱数が偏っています。なぜですか?
MacOSのstdlib.hにあるrand関数は、線形合同法に基づいた乱数生成アルゴリズムを使用しています。このアルゴリズムは、周期が短く、生成される乱数の分布が均等ではないため、偏った乱数が生成される可能性があります。
具体的には、rand関数は0からRAND_MAXまでの範囲の整数を生成しますが、生成される乱数の分布が均等でないため、特定の値がより頻繁に生成される傾向があります。また、線形合同法による乱数生成アルゴリズムは、初期値に依存するため、同じ初期値を使用する場合は、同じ乱数の系列が生成されます。
そのため、rand関数が生成する乱数は、科学的なシミュレーションや暗号学的な目的などのように、高品質な乱数が必要な場合には適していません。代わりに、乱数生成器として、より高品質なアルゴリズムを使用することが推奨されます。たとえば、C++11以降では、<random>ヘッダーに、様々な種類の乱数生成器が用意されています。