2015-03-05 3 views
0

Я делаю игру с помощью 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) 

Я прочел в Интернете и обнаружил, что условие «Пока» ld сделать так, чтобы одно и то же случайное число не генерировалось дважды подряд. Но это все еще происходит.

Может ли кто-нибудь помочь мне в том, как это сделать, поэтому я не получаю одинаковый номер дважды подряд?

+0

Вы можете использовать изменяемый массив, поместить элемент в случайный элемент на последнем месте и вызвать randomNumNew с максимальным значением-1. – Larme

+0

Я понимаю, что вы говорите, но не могли бы вы помочь мне составить код. Я новичок, чтобы быстро и программировать в целом. Если бы вы могли предоставить прямое кодовое решение, которое было бы фантастическим. – PoisonedApps

+0

Посмотрите http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift. –

ответ

5

Код, приведенный ниже, не является случайным для одного и того же номера.

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

Обратите внимание, что это не позволяет вам повторять последнее число, а не все предыдущие числа, что, по-видимому, задает ОП. –

+0

@DavidBerry Пользователь запрашивает «так, чтобы одно и то же случайное число не генерировалось дважды подряд». –

+0

@ Булина может дать этот код в объективе c? –

0

Я думаю Larme's suggestion довольно умный, фактически.

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

Как преобразовать массив в массив NSMutable? – PoisonedApps

+0

Вы можете использовать его, используя 'as', но я не уверен, что понимаю, почему вы спрашиваете. Быстрое 'Array' допускает мутацию. –

0

Я бы рекомендовал не использовать while() петли с рандомизаторами.

Теоретически это может привести к бесконечным циклам в худшем случае, в более положительном сценарии он просто займет несколько циклов, прежде чем вы получите желаемые результаты.

Вместо этого я бы посоветовал сделать NSArray всех значений, удалить из этого раннего рандомизированного элемента NSArray и рандомизировать любые другие существующие элементы из такого массива - это результат гарантии только после одной рандомизации итерации.

Это может быть легко достигнуто путем категории NSArray в Objective-C:

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

Если вы можете использовать , то вы можете выбрать случайное значение, которое не соответствует последнему значению. Затем для любых значений слева вы можете прокручивать и находить допустимые места для их вставки.

Это не самый эффективный, но он работает.

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