2013-04-11 50 views
2

在我的.NET遊戲中,我的rand函數正在確定玩家每個角色應該承受多少傷害,然而第一個角色似乎總是處於底部,最後一個在頂部。因此,在我的Character[0]中,傷害很少會比最小蘭幣值多1以上,並且對於較高指數的每個Character,所造成的傷害只會隨着比例較高而隨機化。隨機數表現怪異,不完全隨機

public int GetDamage(int low, int high) 
{ 
    Random r = new Random(); 
    int rand = r.Next(low, high); 
    return rand; 
} 

這是我使用的隨機函數發生器。然後,我更新離開這樣的健康:

int Damage = GetDamage(3, 10); 
Characters[Target].Health = Characters[Target].Health - Damage; 

在這個例子中傷害劃分是這樣的:

Number 1: 3-4 
Number 2: 4-6 
Number 3: 5-7 
Number 4: 7-8 
Number 5: 8-9 
+3

真的嗎?一個非種子隨機發生器不是真的隨機? – 2013-04-11 12:59:27

+0

@ThorstenDittmar它在技術上是種子,只是'很糟糕'。 – 2013-04-11 13:01:09

+1

相關:http://stackoverflow.com/questions/1785744/how-do-i-seed-a-random-class-to-avoid-getting-duplicate-random-values – Carsten 2013-04-11 13:02:36

回答

9

你必須重複使用相同的隨機實例,否則,因爲它是與當前時間作爲種子創建的,你不會得到真正隨機值。如果您撥打GetDamage的速度非常快(例如在循環中),您將始終獲得相同的值。

因此,要麼使用GetDamage的類中的字段/屬性,要麼將隨機實例傳遞給該方法。

private Random _rnd = new Random(); 
public int GetDamage(int low, int high) 
{ 
    int rand = _rnd.Next(low, high); 
    return rand; 
} 

MSDN

從種子值的隨機數生成開始。如果重複使用相同的 種子,則會生成相同的一系列數字。一種產生不同序列的方法是使種子值 具有時間依賴性,由此產生與每個新的Random實例不同的系列。默認情況下,Random類的無參數構造函數使用系統時鐘生成其種子值,而其參數化構造函數的 可以基於當前時間內的 數量的滴答取Int32值。但是,由於時鐘具有有限分辨率,因此使用無參數構造函數創建 不同的隨機對象會緊密連續生成隨機數 生成器,以生成相同的隨機數序列。 這個 問題可以通過創建一個單獨的Random對象而不是 多個來避免。

+0

附註:當在多個'Threads'上使用相同的'Random'對象時,'Random'應該被同步,否則它將只返回'0'。 – Nolonar 2013-04-11 13:06:04

+0

不知道'隨機'是從當前時間+1預先播種的好例子。 – 2013-04-11 13:06:30

+0

非常感謝。現在就像發條一樣:) – Tom 2013-04-11 13:06:43

3

你需要讓你的Random實例變成靜態的,這會給它一次種子,之後你會得到一個更隨機的數字。

static Random r = new Random(); 

public int GetDamage(int low, int high) 
{ 
    int rand = r.Next(low, high); 
    return rand; 
} 
+0

非常感謝,現在工作順利:D – Tom 2013-04-11 13:05:53