【问题标题】:Random number behaves weird, not fully random随机数的行为很奇怪,不是完全随机的
【发布时间】:2013-04-03 16:27:15
【问题描述】:

在我的 .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;

在这个例子中,dmg 是这样划分的:

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

【问题讨论】:

  • 哦,真的吗?非种子随机生成器不是真正随机的吗?
  • 虽然不需要讽刺。
  • 播种如何使其“更加”随机?真正的问题是,将创建多个 Random 实例,可能使用 same 种子(毫秒)产生相同的伪随机数序列。经验法则:为您的整个应用程序拥有 一个 Random 实例,除非您确切知道为什么需要多个实例。

标签: c# .net visual-studio-2010


【解决方案1】:

您必须重复使用相同的随机实例,否则您将无法获得真正的 随机 值,因为它是以当前时间作为种子创建的。如果您非常快地调用GetDamage(例如在循环中),您将始终获得相同的值。

所以要么使用GetDamage 类中的字段/属性,要么将随机实例传递给方法。

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

MSDN

随机数生成从种子值开始。如果一样 重复使用种子,生成相同的数字序列。一 产生不同序列的方法是使种子值 时间相关,从而产生不同的系列与每个新的 随机的实例。默认情况下,无参数构造函数 Random 类使用系统时钟生成其种子值,而 它的参数化构造函数可以采用一个 Int32 值,基于 当前时间的刻度数。然而,由于时钟有 有限分辨率,使用无参数构造函数创建 不同的随机对象连续创建随机数 产生相同随机数序列的生成器。 这个 可以通过创建单个 Random 对象而不是 多个。

【讨论】:

  • 附注:当在多个Threads 上使用相同的Random 对象时,Random 应该同步,否则它将只返回0
  • 不知道 Random 是从当前时间 +1 预播的好例子。
  • @Tom 不要忘记接受最适合您的答案;)
  • @Nolonar 等待计时器结束 :P 我已经接受了我之前所有问题的答案 :)
【解决方案2】:

您需要将您的 Random 实例设为静态,这将为其播种一次,然后您将获得一个看起来更随机的数字。

static Random r = new Random();

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

【讨论】:

    【解决方案3】:

    您需要为随机数生成器播种。

    见:How do I seed a random class to avoid getting duplicate random values

    这里有数百个这样的问题,看看周围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 2013-11-12
      • 2018-05-27
      • 1970-01-01
      • 2017-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多