2009-09-29 61 views
5

好吧,我有一個骰子扔應用程序...C#代碼只在步驟中給出預期的結果?

當我通過代碼它的功能正常和'結果'包含正確數量的投擲結果,他們似乎是隨機的,當我離開代碼運行並做完全相同的事情,它會產生一組相同的數字。

我確定這是一個邏輯錯誤,我看不到,但幾個小時擺弄它沒有改善情況,所以任何幫助都非常appriciated。 :)

class Dice 
{ 

    public int[] Roll(int _throws, int _sides, int _count) 
    { 
     Random rnd = new Random(); 
     int[] results = new int[_throws]; 
     // for each set of dice to throw pass data to calculate method 
     for (int i = 0; i < _throws; i++) 
     { 
      int thisThrow = Calculate(_sides, _count); 
      //add each throw to a new index of array... repeat for every throw 
      results[i] = thisThrow; 
     } 

     return results; 
    } 


    private int Calculate(int _sides, int _count) 
    { 
     Random rnd = new Random(); 
     int[] result = new int[_count]; 
     int total = 0; 
     //for each dice to throw put data into result 
     for (int i = 0; i < _count; i++) 
     { 
      result[i] = rnd.Next(1, _sides); 
     } 
     //count the values in result 
     for (int x = 0; x < _count; x++) 
     { 
      total = total + result[x]; 
     } 
     //return total of all dice to Roll method 
     return total; 
    } 
} 

回答

12

的第一個錯誤:不要使用隨機的多個實例,使用單個實例,並傳遞以及其他參數。

+0

感謝修改:) – Yoda 2009-09-29 13:35:35

+0

該死的快速繪製! – 2009-09-29 13:36:40

+1

@Ian:我已經看到這發生了很多次,不能立即發現:) – leppie 2009-09-29 13:37:39

-1

給構造函數Random一個種子。那就是問題所在。

http://msdn.microsoft.com/en-us/library/aa329890%28VS.71%29.aspx

Random r = new Random(DateTime.Now.Millisecond); 
+2

使用毫秒作爲種子甚至比默認的Ticks更糟糕。剔種子在大多數情況下都很好,正如其他人所說的那樣,不要重新創建隨機類,因此會將其重新設爲相同的值。 – 2009-09-29 13:40:55

+0

啊。我很習慣C風格的rand函數。 – 2009-09-29 13:59:17

5

當您創建「Random rnd = new Random();」它是目前播種的。當你調試你的代碼時(這需要時間),每次都會有不同的種子。

創建1個隨機的實例,並引用到處。

1

您每次需要創建一個數字時都會創建一個隨機類。這樣做會給你堅果結果。

在這裏看到:FROM MSDN

這個問題可以通過創建一個單一的隨機對象,而不是多個被避免。

爲了提高性能,創建一個隨機對象隨着時間的推移生成許多隨機數,而不是重複創建一個新的隨機對象來生成一個隨機數。

E.g.創建隨機的私有實例...

1

除了什麼已經被前面提到的......

使用隨機的東西像骰子,紙牌遊戲,選擇隨機圖像等等。如果您爲了安全起見需要創建一個隨機數,請使用System.Security.Cryptography.RandomNumberGenerator。這個簡單的例子顯示創建一個隨機整數。

 RandomNumberGenerator gen = RandomNumberGenerator.Create(); 
     byte[] myBytes = new byte[4]; 
     gen.GetBytes(myBytes); 
     int myValue = (BitConverter.ToInt32(myBytes, 0)); 

除非您有安全需求,否則請勿使用此功能。性能比Random類低。我想你可以用它來種子隨機,但這可能是矯枉過正。

編輯:它發生在我身上,我從未測試過這個。快速性能測試顯示如下:

1,000,000個隨機數: RandomNumberGenerator:2.6秒 隨機:.015秒。

So隨機約快150倍。

+2

有兩件事。首先,使用一個隨機數播種一個僞隨機數發生器實際上並不會讓你更具隨機性;僞RNG的輸出仍然是可預測的。 – 2009-09-29 15:05:58

+1

其次,密碼強度RNG的性能不僅在它必須做的數學上進行門控,而且也在機器爲RNG提供* entropy *的能力上進行門控。 RNG不會從無到有發明熵,你知道!這個熵必須來自某個地方,而熵就像帶寬,內存或處理器時間一樣,都是有限的資源。你每秒只能得到如此之多的熵;嘗試使用大量的熵當然會阻塞,直到有更多的熵可用,就像試圖使用處理器或網絡帶寬塊一樣。 – 2009-09-29 15:07:30