Выбор случайных вариантов (тянем карты из колоды)
Как эффективнее всего организовать алгоритм выбора из рандомного диапазона с отбросом уже сыгравших чисел?
Т.е. например, у меня по ходу игры есть 10 вариантов чего-то. И игрок может десять раз натыкаться на один из этих вариантов, в случайном порядке, но повторяться варианты не должны.
И конечно нужно добавить условие срабатывающее когда варианты кончились.
Посмотри мой бой.
Так?
MasterSet,
самым правильным решением будет сделать так:
1. завести массив с вариантами(например, 4 варианта - ‘A’, ‘B’, ‘C’, ‘D’)
Первая итерация:
2. выбрать из массива случайный элемент, соотв. длине массива - rand(1, 4)
3. допустим, выпало 2. мы запоминаем соотв. элемент массива - ‘B’
4. удаляем отработанный элемент из массива
5. получаем массив ‘A’, ‘C’, ‘D’
6. возвращаем результат - ‘B’
Вторая итерация:
7. выбрать из массива случайный элемент, соотв. длине массива - rand(1, 3)
8. допустим, выпало 1. мы запоминаем соотв. элемент массива - ‘A’
9. удаляем отработанный элемент из массива
10. получаем массив ‘C’, ‘D’
11. возвращаем результат - ‘A’
…
Продолжаем до тех пор, пока не кончатся все элементы. Всего будет 4 итерации - столько же, сколько изначально было вариантов.
Эээ… а как задавать случайный элемент равный длине массива?
И вообще сложно как-то совсем выходит. Как это сделать сложно я уже три варианта придумал. Неужели более эргономичных вариантов нету? (
Евген, что-то я не вижу где у тебя там что-либо подобное присутствует.
Я наверно вопроса не понял. Rand есть, варианты есть. Что ещё нужно?
Нужно чтобы каждый вариант мог быть задействован лишь однажды. Без повторений. И когда задействованы все, то всё это не сваливалось в бесконечный цикл.
Размер массива можно определить с помощью ф-и ARRSIZE.
Ок, спасибо.
Но я уже реализовываю один из собственных вариантов. Все-равно так легче не выйдет.
MasterSet,
есть и более простые способы, я просто описал самый правильный.
Ну это правильно. Но я давно уже отчаялся делать все правильно. Лучше сделаю по индусски, зато хоть до результатов доберусь.
Написал функцию, которая работает по описанному мной алгоритму. Операции производятся с массивом $random.
Тестовый пример использования функции:
$random[0]='A'
$random[1]='B'
$random[2]='C'
$random[3]='D'
$random[4]='E'
$random[5]='F'
$random[6]='G'
i = 1
:loop
$rand = FUNC('Тянуть карту')
'Шаг №<<i>>. Значение: <<$rand>>'
i = i + 1
IF i <= 7:
JUMP 'loop'
END
Локация “Тянуть карту” (функция):
! Запрашиваем длину массива
_length = ARRSIZE('$random')
! Если вариантов уже нет, возвращаем 'ERROR'
IF _length = 0:
$RESULT = 'ERROR'
EXIT
END
! Выбираем из массива случайный элемент, соотв. длине массива
_variant = RAND(0, _length-1)
! Запоминаем результат
$RESULT = $random[_variant]
! Удаляем отработанный элемент
KILLVAR '$random', _variant
Назвал “тянуть карту”, т.к. операция последовательного случайного выбора схожа с вытягиванием карты из перетасованной колоды.
я бы предпочел сделать проще) задать массив, как уже сказал Nex, а затем упростить до проверки с прыжками.
я пробовал написать код, но что-то подзабыл…
алгорит такой:
1. создаем новый массив рандом1
2. присваиваем первому элементу нового массива рандомное значение
3. присваиваем второму элементу нового массива рандомное значение
4. сравниваем новоявленный рандомный элементы со всеми предыдущими через jump.
5. присвавием N+1ому элементу нового массива рандомное значение
6. повторяем шаги 4 и 5 до посинения)
думаю это как раз то, о чем спрашивал MasterSet.
в принципе организовать легко… но я сейчас не в состоянии))
эххх… а у меня ведь дайсы где-то были с похожей реализацией)
вот, прикладываю… глянь “бросить кости v1.01”. Там не то, что тебе нужно, но проверка, о которой я говорю уже есть…
Ссылка для скачивания файла Dice.rar
http://file.qip.ru/file/PyK7E1uv/Dice.html ( 43,45 Кб )