【问题标题】:Random number from an array without repeating the same number twice in a row?数组中的随机数而不连续两次重复相同的数字?
【发布时间】:2015-03-05 14:56:32
【问题描述】:

我正在使用 Swift 和 SpriteKit 制作游戏,我根据数组将对象移动到随机位置。

由CGPoints组成的数组:

let easyArray = [CGPointMake(0,0), CGPointMake(126.6,0),   CGPointMake(253.4,0), CGPointMake(0,197.5), CGPointMake(126.7,197.5), CGPointMake(253.4,197.5), CGPointMake(0,395), CGPointMake(126.7,395), CGPointMake(253.4,395)]

我用这个函数来生成一个随机数:

func randomNumber(maximum: UInt32) -> Int {

    var randomNumber = arc4random_uniform(maximum)
    while previousNumber == randomNumber {
    randomNumber = arc4random_uniform(maximum)
}
    previousNumber = randomNumber
    return Int(randomNumber)
}

我使用它根据生成的随机数移动对象:

let greenEasy = randomNumberNew(9)
let moveSelector = SKAction.moveTo(easyArray[greenEasy], duration: 0)
selector.runAction(moveSelector)

我在网上做了一些阅读,发现“While”条件应该使它不会连续生成两次相同的随机数。但它仍然会发生。

谁能帮我弄一下,这样我就不会连续两次得到相同的数字了?

【问题讨论】:

  • 您可以使用可变数组,将项目放在最后一个位置的随机项目上,然后调用 randomNumNew 最大值为1。
  • 我明白你在说什么,但你能帮我写代码吗?我是一个快速编程的菜鸟。如果您能提供一个直接代码解决方案,那就太棒了。

标签: ios arrays swift sprite-kit arc4random


【解决方案1】:

下面的代码不会随机取同一个数字。

   var currentNo: UInt32 = 0

    func randomNumber(maximum: UInt32) -> Int {

        var randomNumber: UInt32

        do {
            randomNumber = (arc4random_uniform(maximum))
        }while currentNo == randomNumber

        currentNo = randomNumber

        return Int(randomNumber)
    }

【讨论】:

  • 请注意,这只会阻止您重复最后一个数字,而不是所有以前的数字,这似乎是 OP 要求的。
  • @DavidBerry 用户要求“以便同一随机数不会连续生成两次。”
【解决方案2】:

我认为Larme's suggestion 实际上很聪明。

easyArray.append(easyArray.removeAtIndex(Int(arc4random_uniform(UInt32(easyArray.count)-1))))
selector.runAction(SKAction.moveTo(easyArray.last!, duration: 0))

【讨论】:

  • 如何将数组转换为 NSMutable 数组?
  • 您可以使用as 投射它,但我不确定我是否理解您为什么要问。 swift Array 允许突变。
【解决方案3】:

我建议不要将 while() 循环与随机器一起使用。

理论上,在最坏的情况下它会导致无限循环,在更积极的情况下,它只需要几个循环就可以得到想要的结果。

相反,我建议创建一个包含所有值的 NSArray,从这个 NSArray 中删除最后一个随机元素,并从这样的数组中随机化任何其他现有元素 - 这是保证仅在一次随机化迭代后的结果。

在Objective-C中制作NSArray类很容易实现:

- (id) randomARC4Element
{
    if(self.count > 0)
    {
        return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
    }

    return nil;
}

- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
    return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}

- (float)randomFloat
{
    return (float) arc4random() / UINT_MAX;
}

【讨论】:

    【解决方案4】:

    如果您可以使用,那么您可以选择一个与最后一个值不匹配的随机值。然后对于任何剩余的值,您可以循环并找到插入它们的有效位置。

    这不是最有效的,但它确实有效。

    public static List<int> Randomize(List<int> reps, int lastId) {
      var rand = new Random();
    
      var newReps = new List<int>();
      var tempReps = new List<int>();
      tempReps.AddRange(reps);
      while (tempReps.Any(x => x != lastId)) {
        var validReps = tempReps.FindAll(x => x != lastId);
        var i = rand.Next(0, validReps.Count - 1);
        newReps.Add(validReps[i]);
        lastId = validReps[i];
        tempReps.Remove(validReps[i]);
      }
      while (tempReps.Any()) {
        var tempRep = tempReps.First();
        bool placed = false;
        for (int i = 0; i < newReps.Count; i++) {
          if (newReps[i] == tempRep) {
            continue;
          }
          else if ((i < newReps.Count - 1) && (newReps[i + 1] == tempRep)) {
            continue;
          }
          else {
            newReps.Insert(i + 1, tempRep);
            placed = true;
            break;
          }
        }
    
        if (placed) {
          tempReps.Remove(tempRep);
        }
        else {
          throw new Exception("Unable to randomize reps");
        }
      }
      return newReps;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-29
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-22
      相关资源
      最近更新 更多