Неповторимый рандом

Разработчик Проект месяца 1 место Ветеран 3 место в Обучающем конкурсе Проект месяца 2 место
Больше
4 года 6 мес. назад - 4 года 6 мес. назад #125204 от DarchanKaen
Неповторимый рандом


[IMG
[IMG


Доброго времени суток!
Вероятно все вы знаете, что в RpgMaker есть переменные и возможность присваивать им случайное значение в некотором диапазоне.
Это бесспорно удобная функция, которую можно использовать для большого количества игровых ситуаций.

Но что делать, если нам нужно, чтобы все случайные значения были уникальными и не повторялись? Например, мы делает игру-викторину с уникальными вопросами или некий текстовой квест со случайными событиями, которые не должны повторяться. Конечно, можно стандартными средствами мейкера, переключателями и проверками условий, но это муторно в настройке и крайне неудобно, когда такого рандома должно быть больше 10 вариантов.

И тут на помощь нам приходит команда скрипт и тот факт, что в мейкере можно выполнять код на JavaScript; так как данный урок для MV (и MZ) в Ruby для Xp-Vx-Vx Ace, вероятно делается схожим подходом, но с другим синтаксисом.

Уточним условия примера. У нас игра-викторина, при которой 9 вопросов должны задаваться в любом порядке, но только по одному разу…то есть не повторяться (число вопросов может быть любым!).
Достигнуть подобного можно, храня перечень номеров вопросов в массиве, который будет хранится в определенной переменной мейкера и, после выбора случайного номера вопроса, данный номер будет удаляться из массива и отфильтровываться.

Для этого выполним несколько простых действий (номера переменных могут быть любыми):

1)В инициализирующем событии, в команде «Скрипт», напишем такой код:
Code:
let randomNumbersList = [1, 2, 3, 4, 5, 6, 7, 8, 9]; $gameVariables.setValue(1, randomNumbersList);

где:
«randomNumbersList» - массив с номерами вопросов;
«$gameVariables.setValue()» - сохранение массива в определенной переменной мейкера.

2)В событии, в котором мы выбираем номер, в команде «Скрипт», напишем такой код:
Code:
let randomNumbersList = $gameVariables.value(1); let randomIndex = Math.floor( Math.random() * randomNumbersList.length ); let randomNumber = randomNumbersList[randomIndex]; $gameVariables.setValue(2, randomNumber); delete randomNumbersList[randomIndex]; let uniqueRandomNumbersList = randomNumbersList.filter( elem => elem ); $gameVariables.setValue(1, uniqueRandomNumbersList);

где:
«$gameVariables.value()» - получение массива с номерами вопросов из переменной мейкера и сохранение его во временную переменную «randomNumbersList»;
«randomIndex» - получение случайного индекса массива, под которым хранится номер вопроса;
«randomNumber» - получение номера вопроса при помощи случайного индекса массива;
«$gameVariables.setValue()» - здесь это сохранение выбранного номера вопроса в определенной переменной мейкера;
«delete randomNumbersList[randomIndex]» - удаление номера вопроса, выбранного по случайному индексу, из массива с вопросами.

И вот тут важный момент! После удаления элементов, в массиве остаются пустые места. Поскольку мы не хотим для выбора вопроса вводить какие-то доп. проверки, нам нужно исключить из массива вопросов эти самые пустые места. Как? Фильтрацией, а именно:
Code:
«randomNumbersList.filter( elem => elem )»

Данный фрагмент кода возвращает массив с номерами вопросов, но уже без пустых мест. Ну и дальше мы привычным способом сохраняем его в переменную мейкера, причем в ту же, в какую писали при инициализации:
Code:
«$gameVariables.setValue»

Как видите, несколько строчек кода позволяет удобным способом сделать нам рандом неповторимым и уникальным.

Ну а сами номера вопросов в нужном событии мы используем в условии по переменной, в которой сохранили номер.

И с каждым вызовом скрипта из пункта №2 массив с вариантами ответов будет уменьшаться...пока не достигнет нуля и массив будет пустым, весь. Поэтому количество ответов / случайных событий / для чего вы это используете нужно контролировать, как минимум учитывая в отдельной переменной сколько раз этот рандом уже использовали (в нашем случае - сколько ответов уже дали).

Вот и все, спасибо за внимание!

P.S: допускаю, что такой урок уже был – но поиском я не нашел…в случае, если такое уже было – смело снимайте с конкурса.

update-1 от 10.11.2021
Спасибо Lekste, он напомнил, как важно правильно называть переменные.
Изменен код, в фильтрации "index" заменен на "elem", так как первая переменная фильтра - элемент массива.

И Lekste прав, есть еще один вариант кода фильтрации, без удаления элемента из массива, а именно:
Code:
randomNumbersList.filter( (elem, index) => index != randomIndex );
где
"elem" - элемент массива, первый параметр фильтра;
"index" - собственно индекс элемента;
в условии фильтрации указываются, что возвращаются все индексы, кроме равного случайно выбранному.
При использовании такого подхода удаление при помощи:

"delete randomNumbersList[randomIndex];"

уже не нужно!
Последнее редактирование: 4 года 6 мес. назад пользователем DarchanKaen.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Проект месяца 3 место Оратор Тестер
Больше
4 года 6 мес. назад #125208 от VeselyRodger
Полезно

Мои проекты:
rpgmakerunion.ru/user/veselyrodger
Мой канал на Ютубе:
youtube.com/channel/UCyttExMfXo8ke_PhQjNPyuw
Спасибо сказали: DarchanKaen, SirAndriy

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 2 место
Больше
4 года 6 мес. назад #125209 от xrenj
xrenj ответил в теме Неповторимый рандом
Интересно было, о таком использовании рандома раньше не думал.
Спасибо сказали: DarchanKaen

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 2 место Проект месяца 1 место Коммерсант
Больше
4 года 6 мес. назад #125214 от alexgunwork
Вероятно все вы знаете, что в RpgMaker есть переменные и возможность присваивать им случайное значение в некотором диапазоне.
— а вот в этом месте поподробней. А как она работает?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 1 место Ветеран 3 место в Обучающем конкурсе Проект месяца 2 место
Больше
4 года 6 мес. назад - 4 года 6 мес. назад #125215 от DarchanKaen

alexgunwork пишет: Вероятно все вы знаете, что в RpgMaker есть переменные и возможность присваивать им случайное значение в некотором диапазоне.
— а вот в этом месте поподробней. А как она работает?

[IMG
[IMG


При вызове этой опции в переменную каждый раз заносится случайное значение из диапазона.
Последнее редактирование: 4 года 6 мес. назад пользователем DarchanKaen.
Спасибо сказали: alexgunwork

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Ветеран Даритель Стимкея Оратор Программист JavaScript
Больше
4 года 6 мес. назад - 4 года 6 мес. назад #125216 от Lekste
Lekste ответил в теме Неповторимый рандом
А зачем удалять и фильтровать, когда можно сразу отфильтровать по условию: index != randomIndex?
Последнее редактирование: 4 года 6 мес. назад пользователем Lekste.
Спасибо сказали: DarchanKaen, yuryol

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Разработчик 3 место 3 место в Обучающем конкурсе Учитель Оратор 1 место в Обучающем конкурсе Паладин Проект года 3 место Проект года 1 место
Больше
4 года 6 мес. назад #125217 от Alx_Yago
Alx_Yago ответил в теме Неповторимый рандом

Lekste пишет: А зачем удалять и фильтровать, когда можно сразу отфильтровать по условию: index != randomIndex?


Разверните мысль. Как всё будет работать в этом случае?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 1 место Ветеран 3 место в Обучающем конкурсе Проект месяца 2 место
Больше
4 года 6 мес. назад - 4 года 6 мес. назад #125218 от DarchanKaen

Lekste пишет: А зачем удалять и фильтровать, когда можно сразу отфильтровать по условию: index != randomIndex?

Правильный вопрос.

Начнем с того, что я неверно назвал параметры в фильтре, ведь первый параметр (который по-умолчанию) не индекс - а сам элемент.
Индекс - второй параметр, опциональный. Используя его и такое условие действительно можно не удалять, а сразу фильтровать.

Такой код корректно работает и не требует предварительного удаления элемента:
Code:
randomNumbersList.filter( (elem, index) => index != randomIndex );

Добавил секцию update с примером кода и скорректировал название параметра фильтра в основной секции.
Спасибо за толчок в правильном направлении!
Последнее редактирование: 4 года 6 мес. назад пользователем DarchanKaen.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 3 место Проект месяца 2 место Учитель
Больше
4 года 6 мес. назад #125255 от nirion
nirion ответил в теме Неповторимый рандом
Демку бы, а то у меня, много уточняющих вопросов.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 1 место Ветеран 3 место в Обучающем конкурсе Проект месяца 2 место
Больше
4 года 6 мес. назад - 4 года 6 мес. назад #125264 от DarchanKaen
Вот демо для MV, проект нужно открыть редактором.
Самое интересное - в Общих событиях.

www.mediafire.com/file/0jpqxxj2pgo8nzu/D...dom_Demo_MV.zip/file

P.S:
Можно открыть и MZ, если подбросить в папку проекта файл game.rmmzproject, взятый из любого проекта MZ.
Последнее редактирование: 4 года 6 мес. назад пользователем DarchanKaen.
Спасибо сказали: xrenj

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 2 место
Больше
4 года 3 мес. назад #126056 от xrenj
xrenj ответил в теме Неповторимый рандом
Снова вернулся к этому уроку, задумавшись (возможно, тупой будет вопрос), а возможно ли создать 2 (или более) таких массива для двух или более разных событий? Просто копированием и изменением переменных явно дело не решилось, потому что рандом тут же перестаёт быть рандомом - второе событие повторяет полностью последовательность ответов за первым. А до больше, увы, пока ума не хватает.
Спасибо сказали: DarchanKaen

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Оратор 1 место в Готв 3 место Готв 2 место Учитель Композитор Победитель конкурса Организатор конкурсов
Больше
4 года 3 мес. назад #126058 от yuryol
yuryol ответил в теме Неповторимый рандом

xrenj пишет: Снова вернулся к этому уроку, задумавшись (возможно, тупой будет вопрос), а возможно ли создать 2 (или более) таких массива для двух или более разных событий? Просто копированием и изменением переменных явно дело не решилось, потому что рандом тут же перестаёт быть рандомом - второе событие повторяет полностью последовательность ответов за первым. А до больше, увы, пока ума не хватает.


скорее всего надо изменить название у переменной randomNumbersList , например на randomNumbersList_2
Спасибо сказали: DarchanKaen, xrenj

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 2 место
Больше
4 года 3 мес. назад #126066 от xrenj
xrenj ответил в теме Неповторимый рандом
Спасибо, уже закрались подобные мысли, но естественно я переименовал походу неправильно, или затронул что-то лишнее, попробую снова именно так.
Спасибо сказали: DarchanKaen

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Разработчик Проект месяца 1 место Ветеран 3 место в Обучающем конкурсе Проект месяца 2 место
Больше
4 года 3 мес. назад - 4 года 3 мес. назад #126070 от DarchanKaen
Можно иметь несколько таких массивов и несколько случайных переменных.
Например, для 2-х (A и B)
Последнее редактирование: 4 года 3 мес. назад пользователем DarchanKaen.
Спасибо сказали: Alx_Yago, xrenj

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
4 года 3 мес. назад - 4 года 3 мес. назад #126188 от Sleeping Visitor
VX Ace:

Можно сделать очень простую систему.

Пишем генерацию рандома для викторины:

ВНИМАНИЕ: Спойлер!


Как это в теории должно работать:

ВНИМАНИЕ: Спойлер!
Последнее редактирование: 4 года 3 мес. назад пользователем Sleeping Visitor.
Спасибо сказали: DarchanKaen

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Время создания страницы: 0.136 секунд
Работает на Kunena форум