5

重複の可能性:
1 つの乱数のみを生成する乱数ジェネレーター

この数分前、私は少し当惑しました。次のコードがあります。

public blockType generateRandomBlock()
{
    Random random = new Random();
    int makeBlockOfType = random.Next(0, 100);

    blockType t = blockType.normal;
    if (makeBlockOfType <= 80 && makeBlockOfType >= 60)
    {
        t = blockType.blue;
    }
    else if (makeBlockOfType > 80 && makeBlockOfType <= 95)
    {
        t = blockType.orange;
    }
    else if (makeBlockOfType > 95 && makeBlockOfType <= 100)
    {
        t = blockType.green;
    }

    return t;
}

かなり単純で、enum(システム時間に基づいて) ランダムに生成された数値に基づいて値を返します。残念ながら、いくつかの奇妙な理由で、これはゲームに投入されるすべてのブロックに対して実行されますが、すべてのブロックが 1 つの色または他の色のいずれかになります。ただし、デバッガーでこれをステップ実行し、実行後に結果を確認すると、提供された可能性に基づいてブロックがマルチカラーになっていることがわかります。なぜこれが起こっているのか、少し混乱しています。

このために、Microsoft の代わりに Mono コンパイラを使用する MonoGame を使用しています。これが問題でしょうか?このコードを呼び出し元のコンストラクターにインラインで配置しようとしましたが、同じ結果が得られます (とにかくコンパイラーがコードをインライン化すると推測しています)。

ビルドを実行させるのではなく、Visual Studio を個別に再起動しようとしました。変更はありません。

どんな提案や助けも大歓迎です!

4

3 に答える 3

7

Random を 1 回だけインスタンス化する必要があります (プライベート フィールドとして設定し、コンストラクターでインスタンス化します)。同様の質問を参照してください: Random.Next は常に同じ値を返します。

ランダムのドキュメントを参照してください。

乱数の生成はシード値から始まります。同じシードを繰り返し使用すると、同じ一連の数値が生成されます

あなたの場合、同じシード (時間が近すぎる) で Random インスタンスを作成し、特定のシードに対して同じになる最初の値を取得します。

于 2012-12-12T14:18:19.080 に答える
4

メソッドを呼び出すたびに、乱数ジェネレーターを再作成します。

public blockType generateRandomBlock()
{
    Random random = new Random();

乱数ジェネレーターのシードは時間に基づいているため、これは連続した呼び出しに対して同じ値を返します。

ジェネレーターの作成をルーチンの外に移動します。

Random random = new Random();
public blockType generateRandomBlock()
{
于 2012-12-12T14:18:44.923 に答える
3

非常に短い期間に複数のインスタンスをRandom連続して作成すると、同じ時間依存のシード値で初期化される可能性があります。

これを回避するには、Random代わりにインスタンス フィールドとして初期化する必要があります。

private readonly Random random = new Random();

public blockType generateRandomBlock()
{
    int makeBlockOfType = random.Next(0, 100);

    // ...
}
于 2012-12-12T14:18:14.557 に答える