2013-04-11 111 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