【问题标题】:Random number with no repetition无重复的随机数
【发布时间】:2013-03-12 11:57:45
【问题描述】:

我想做的是让我正在创建的游戏每 5 秒随机更改一次角色。 我通过计时器得到了这个工作,唯一的问题是我不希望他们重复,我目前正在处理虚拟代码,所以它只是改变屏幕颜色,但我怎样才能让它不重复它刚刚调用的号码?

if (timer <= 0)
{
    num = rand.Next(2);
    timer = 5.0f;   
}

这是当前代码,然后在抽奖中我刚刚完成了“如果 num 等于某个数字,则更改背景颜色”。

我尝试添加一个 prev_num 检查器,但我无法让它正常工作(在这里)

if (timer <= 0)
{
    prev_number = num;
    num = rand.Next(2);
    if (prev_number == num)
    {
        num = rand.Next(2);
    }
    else
    {
        timer = 5.0f;
    }
}

【问题讨论】:

  • 一个真正的随机数将包括重复,因此尝试排除这意味着该数字不是真正随机的
  • @JoeW 我认为这就是重点,否则 rand.Next() 就足够了
  • @Hannesh 点是不是随机的随机数?
  • @JoeW 至少在定义上不是随机的
  • @JoeW,最终目标是从字符集中选择一个随机字符,不包括当前字符。不只是为了得到任何随机数。无论如何,rand.Next(2) 不太可能是真正随机的,无论您尝试什么。

标签: random xna numbers repeat


【解决方案1】:

考虑一下,如果您选择(例如)从 1 到 5 的随机数,则有五种可能的结果,因此您可以使用 rand.Next(5) 选择从零开始的“序数”或结果索引,然后将其转换为您实际想要的范围(在这种情况下,通过添加一个)。

如果您想要一个 0-4 的随机数,不包括您刚刚选择的数字,那么只有四种可能的结果,而不是五种 - 如果之前的数字是 3,那么可能的结果是 0、1、2 或4. 然后,您可以通过选择这四个结果之一 (rand.Next(4)) 并将该序数映射到您想要的范围来简化您的算法。一个简单的映射是说如果新的随机数低于前一个数字,则按原样返回,否则(如果相等或更大)加一。

int new_num = rand.Next(4);
if(new_num >= prev_num)
{
    new_num++;
}

您的新号码现在保证与以前的号码在同一范围内,但不等于它。

【讨论】:

    【解决方案2】:

    也许只是将其放入循环而不是单个检查?
    另外,我认为因为您的计时器在else 内,所以并不总是 正确更新。

    if (timer <= 0)
    {
        tempNum = rand.Next(2);
    
        do
        {
            tempNum = rand.Next(2);
        }
        while (tempNum == num)
    
        num = tempNum;
        timer = 5.0f;
    }
    

    【讨论】:

      【解决方案3】:

      创建一个序列号数组,然后在您的应用程序开始时将它们洗牌(就像一副纸牌)。

      int[] numbers = new int[100];
      for(int i = 0; i < numbers.Length; i++)
          numbers[i] = i;
      Shuffle(numbers);
      

      使用函数打乱列表:

      public static void Shuffle<T>(IList<T> list)  
      {  
          Random rng = new Random();  
          int n = list.Count;  
          while (n > 1) {  
              n--;  
              int k = rng.Next(n + 1);  
              T value = list[k];  
              list[k] = list[n];  
              list[n] = value;  
          }  
      }
      

      然后您可以从列表中按顺序访问它们。当列表被打乱时,它们将是随机的,但您不会有任何重复,因为每个数字在列表中只存在一次。

      if (timer <= 0)
      {
          num = numbers[index];
          index++;
          timer = 5.0f;   
      }
      

      【讨论】:

        猜你喜欢
        • 2012-06-29
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        • 2021-06-24
        • 2014-01-11
        • 2014-03-22
        相关资源
        最近更新 更多