1

C++ で 2 つの乱数をすばやく生成する方法を探しています。コードはサイコロ用で、ロール時に乱数を生成する必要があります。私のコードは現在次のようになっています。

Die::Die() {
    srand(time(NULL));
}

void Die::roll() {
    value = rand() % 6 + 1;
}

このコードで 2 つのオブジェクトを作成すると、srand() は静的 (非インスタンス ベース) 関数であり、すべてのオブジェクトの新しいシードを生成します。私もこれをやってみました:

void Die::roll() {
    srand(time(NULL));
    value = rand() % 6 + 1;
}

コンストラクターに入れるのではなく、次のようにすばやく呼び出すと:

die0->roll();
die1->roll();

通常、それらの値は同じです。毎回これを実際にランダムにする方法はありますか? ご助力いただきありがとうございます。:)

4

4 に答える 4

4

プログラムが十分に速く実行されていると仮定すると、時間 (秒単位) は通常同じになります。つまり、シードが同じになり、ランダム値が同じになることを意味します。コメント者が言ったように、ランダムシードを他の場所で行います(プログラムやスレッドの開始など)。

于 2013-08-19T12:08:50.323 に答える
1

問題は、srand が時間的に十分に接近して発生する場合、rng に同じ値をシードしているため、各シードの後に​​取得する最初の値が同じになることです。これを回避するために、シード処理が 1 回だけ行われるようにすることができます。たとえば、Die クラスから srand を削除し、Die を最初に使用する前にシードすることができます。

あるいは、Die のコンシューマーに srand を呼び出す負担を負わせたくない場合は、Die のコンストラクターに srand を保持し、静的 bool を使用して複数回呼び出さないようにすることができます。

Die::Die()
{
  static bool seeded = false;
  if (!seeded)
  {
    srand(time(NULL));
    seeded = true;
  }
}

この srand は srand() と rand() の他のクラスに影響を与える可能性がありますが、問題にならない可能性があります。ただし、定義している複数のクラス内で乱数が必要な場合は、RNG シングルトンを作成して数値を生成することを検討できます。

于 2013-08-19T12:28:35.807 に答える
0

他の人が言ったように、ジェネレーターを複数回再シードしたくありません。Dieの唯一のユーザーである場合rand(またはそうでない場合でも)、名前空間スコープで変数を使用してシードすることができます。

int seeded = (srand( time( NULL ) ), rand());

これが良いアイデアかどうかは、状況によって異なります。たとえば、デバッグ目的でコードの実行を複製することができなくなります。これが問題になる場合は、1) 使用するシードをログに記録し、2) シードを指定するオプションをコマンド ラインに追加します。後者はsrandから 呼び出すことを意味しmainます。

(初期化に への呼び出しを追加したことにも注意してくださいrand()。少なくとも 1 つの広範な実装では、への最初の呼び出しがrand()シードを返します。つまり、非常に予測可能です。)

于 2013-08-19T13:12:16.917 に答える