Новый arc4random()%x; отличается от предыдущего номера

У меня есть эта строка кода для вычисления случайного числа:

    myRand = arc4random()%24; //0:23

Каков наиболее эффективный способ добавить к этому, чтобы это не генерировало то же число, которое было создано ранее.

Я не пытаюсь перетасовать все 24, так как мне нужны повторы, просто желательно не 2 одинаковых числа сразу друг за другом...

Я думал сохранить предыдущее число отдельно, затем сравнить его и, если оно совпало, просто сделать это снова, но я не мог понять, если, например, одно и то же число выпало 3 раза подряд... Вряд ли я знаю, но это возможно.

Спасибо.


person Reanimation    schedule 30.11.2015    source источник
comment
Я просто генерирую случайное число, которое соответствует расположению врага внутри круга (с 24 сегментами)... они появляются в каждом сегменте в зависимости от сгенерированного числа... Я бы не хотел, чтобы они появлялись в круге. одно и то же место два раза подряд...   -  person Reanimation    schedule 01.12.2015
comment
Добавьте дополнительную информацию к вопросу. Кроме того, если 3 раза подряд, что должно произойти? И вместо arc4random()%24; используйте arc4random_uniform(24);, это устранит любую погрешность в операции остатка.   -  person zaph    schedule 01.12.2015
comment
Цифры не манипулируются, поэтому я подумал, что arc24random будет в порядке... Ничего не происходит, как я уже говорил, я не хочу, чтобы предыдущее число снова появлялось, и единственный способ, которым я мог придумать сравнение, - это сохранить его. и сравните два ... но, очевидно, скажите, что одно и то же число было сгенерировано 5 раз подряд, мой метод не сможет сравнить их все ... Следовательно, спрашивая, как все это можно было бы решить до того, как число получит шанс появляются более одного раза.   -  person Reanimation    schedule 01.12.2015


Ответы (2)


Сохраните ссылку на ранее сгенерированный номер в ivar.

NSInteger lastRandom;

и инициализируйте его чем-то вроде -1.

Затем, когда вам нужно новое случайное число, вы можете сделать что-то вроде:

NSInteger newRandom;
do {
    newRandom = arc4random_uniform(24);
while (newRandom != lastRandom);
lastRandom = newRandom;

Этот небольшой цикл гарантирует, что ваше новое случайное число отличается от последнего, которое вы сгенерировали.

person rmaddy    schedule 30.11.2015
comment
О сладкий. Я всегда забываю do while и, кажется, никогда не нахожу в этом необходимости... Теперь у меня есть :D - person Reanimation; 01.12.2015

То, что вы ищете, очень похоже на перетасовку карт: вы хотите, чтобы 24 значения выпадали в случайном порядке, и, подобно картам, вы хотите взять каждую из колоды после того, как она выпадет, чтобы она не выпадала снова ( пока вы не перетасуете колоду).

GameplayKit в iOS 9 и более поздних версиях предоставляет утилиты для таких задач рандомизации. В частности, это решается GKShuffledDistribution класс:

id<GKRandom> dist = [GKShuffledDistribution distributionForDieWithSideCount:24];
myRand = [dist nextInt];

Это не повторяется, пока не будут исчерпаны все 24 значения.

В более общем смысле, использование GKRandom (и т. д.) вместо arc4random (и т. д.) дает вам несколько вариантов управления рандомизированным поведением в вашей игре: убедитесь, что разные рандомизированные игровые системы не влияют друг на друга, убедитесь, что вы можете повторять определенные случайные последовательности для тестирования. или между клиентом и сервером, создавая случайные числа, которые следуют определенному шаблону, и так далее.

person rickster    schedule 30.11.2015
comment
Нет, ОП не ищет ничего похожего на перетасовку карт. - person rmaddy; 01.12.2015
comment
Я очень плохо объясняю вещи... У меня есть враг в 1 из 24 локаций, враг появляется в 1 из 24 локаций, в зависимости от генерации чисел... так что мне нужно повторять числа, а не 2 из одно и то же сразу одно за другим... чтобы он мог генерировать 1,2,6,5,19,4,19,2,20,5,7... это было бы нормально. Хотя это полезно знать. Спасибо за публикацию. - person Reanimation; 01.12.2015
comment
distributionForDieWithSideCount хорош, хотя и не отвечает на вопрос. - person zaph; 01.12.2015