簡體   English   中英

來自數組的隨機數,而不是連續兩次重復相同的數?

[英]Random number from an array without repeating the same number twice in a row?

我正在使用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”條件,以使同一隨機數不會連續產生兩次。 但是它仍然發生。

任何人都可以幫我如何做到這一點,這樣我就不會連續兩次得到相同的號碼了嗎?

下面的代碼不會隨機分配相同的數字。

   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)
    }

實際上,我認為Larme的建議非常聰明。

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

我建議不要將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;
}

如果可以使用則可以選擇與上一個值不匹配的隨機值。 然后,對於任何剩余的值,您可以循環查找有效的位置以插入它們。

它不是最有效的,但可以。

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM