2011-02-04 4 views
2

これは偶然のような素晴らしい機能なので、「カード」の配列をシャッフルするのは難しいことです。私が同じ番号を取得しているという事実は、毎回別の種子を選ぶ際に問題があることを示しています。 srand48またはtime(NULL)コールが不適切ですか?私は行方不明のいくつかの根本的な論理欠陥がありますか? time()の値が異なるように繰り返し間に十分な時間がないのですか?私のC乱数ジェネレータはなぜ "42"だけを返しますか?

コードはLinuxで実行されています。

void shuffle() 

{ 
    int i_rnd; /* Integer random number, range 0..100 */ 
    int i_rnd2; 
    card tempCard; /*temporary card to facillitate swapping*/ 
    int i = 0; /*can't use a FOR loop 'cause we're not using c99 standard*/ 
    while(i < 1000) 
    { 

     srand48((unsigned) time(NULL)); /* Seed the random number generator */ 
     i_rnd = (int) (drand48() * 100); 
     i_rnd = i_rnd%52; // return a random number 0-51  
     i_rnd2 = (int) (drand48() * 100); 
     i_rnd2 = i_rnd2%52; // return a random number 0-51 
     /*we have two random numbers, now exchange the two objects with the 
    /picked array indices */ 
     tempCard = cardDeck[i_rnd]; 
     cardDeck[i_rnd]=cardDeck[i_rnd2]; 
     cardDeck[i_rnd2]=tempCard; 
     //swap complete. increment counter so we can eventually get out of the while 
     i++; 

    } 

return; 

} 
+20

42は、人生、宇宙、そしてすべてに対する答えです。 –

+2

プログラムは、不必要に手順を踏まずに**答えを与えています。私はあなたのようなコンピュータを持っていたらいいのに。 – Mehrdad

+0

@あなたは冗談に私を打つ! – Marlon

答えて

14

あなたは、あなたがそれを使用するたびに、一度擬似乱数ジェネレータをしませシードする必要があります。

多くの(ほとんどの)擬似乱数生成器(PRNG)は、特定のシード値が与えられたときに決定論的です。 time()がループを実行するたびに同じ値を返す場合は、毎回同じ値を使用するようにPRNGを渡すので、乱数をクエリすると同じ値が返されます。

+1

ああ。私はwhileループの外にそれを移動します。それは理にかなっている。 –

+5

@Raven:PRNGを 'main()'や 'main()'から呼び出される関数でシードする方が良いでしょう。プログラムを実行するたびに一度正確にシードしたいとします。 –

+2

@Raven:いいえ、あなたの 'main()'に移動してください。シャッフルするたびに種を蒔きたくない。 –

5

乱数ジェネレータには、毎回同じシードのループがあります(1秒未満で実行されるため)。プログラムの冒頭でsrand48() ONCEに電話してください。

0

PRNGは常に決定論的です... PRNGのランダム性は、それの論理によってではなく、それが使用する種によって達成されます。

したがって、ランダム性を達成するために、シードを可能な限りランダムにしてください。

関連する問題