RU

Выбор случайных вариантов (тянем карты из колоды)

MasterSet #11 15.03.2011 20:31 15 comments 14959 views

Как эффективнее всего организовать алгоритм выбора из рандомного диапазона с отбросом уже сыгравших чисел?
Т.е. например, у меня по ходу игры есть 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 итерации - столько же, сколько изначально было вариантов.

Эээ… а как задавать случайный элемент равный длине массива?
И вообще сложно как-то совсем выходит. Как это сделать сложно я уже три варианта придумал. Неужели более эргономичных вариантов нету? (

Размер массива можно определить с помощью ф-и ARRSIZE.

Написал функцию, которая работает по описанному мной алгоритму. Операции производятся с массивом $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

Назвал “тянуть карту”, т.к. операция последовательного случайного выбора схожа с вытягиванием карты из перетасованной колоды.

Dark[Ol(U23)leneri] #34 15.03.2011 23:09 (14 years ago)

я бы предпочел сделать проще) задать массив, как уже сказал Nex, а затем упростить до проверки с прыжками.
я пробовал написать код, но что-то подзабыл…

алгорит такой:

1. создаем новый массив рандом1
2. присваиваем первому элементу нового массива рандомное значение
3. присваиваем второму элементу нового массива рандомное значение
4. сравниваем новоявленный рандомный элементы со всеми предыдущими через jump.
5. присвавием N+1ому элементу нового массива рандомное значение
6. повторяем шаги 4 и 5 до посинения)

думаю это как раз то, о чем спрашивал MasterSet.

в принципе организовать легко… но я сейчас не в состоянии))

Dark[Ol(U23)leneri] #34 15.03.2011 23:12 (14 years ago)

эххх… а у меня ведь дайсы где-то были с похожей реализацией)

Dark[Ol(U23)leneri] #34 15.03.2011 23:16 (14 years ago)

вот, прикладываю… глянь “бросить кости v1.01”. Там не то, что тебе нужно, но проверка, о которой я говорю уже есть…

Ссылка для скачивания файла Dice.rar
http://file.qip.ru/file/PyK7E1uv/Dice.html ( 43,45 Кб )

Nex,
KILLVAR удаляет элемент и сдвигает массив, то есть вместо цикла в конце там можно было сделать

KILLVAR '$random', _variant

Byte,
действительно. Исправил код. Так гораздо проще.

Да, с этим уже можно работать.
Хотя пока что не пригодится. У меня уже готово все давно )

Наверняка будет полезно будущим авторам. Спасиб!

Aleks Versus Moderator 22.03.2011 22:23 (14 years ago)

Так-так-так.
Я опять что-то пропустил. С какой версии плеера работает вот это

Nex:

FUNC

и вот это

Nex:

KILLVAR ‘$random’, _variant

?

Не знаю с какой, качай последнюю.

Оформил в статью.

Log in or Register to post comments.