Инструменты
July 3, 2023

Скрипт для подсчета шансов по весам с вычеркиванием на основе симуляции

Как-то для одной механики нам понадобилось рассчитать шансы выпадения предметов на основе весов, но расчет формулами по математике не складывался из-за сложности условий, и проще было написать скрипт, который «рандомит» несколько тысяч случаев и считает итоговые шансы. Поделюсь скриптом, вдруг кому-то может пригодится.

Обычно, для задания шансов выпадения предметов играх используют понятие Вес. Чем больше вес, тем выше шанс.

Пример: У нас есть сундук, в котором должен выпасть один из трех предметов с разным шансом.

Вес 1-го предмета = 2, Вес 2-го предмета = 3, Вес 3-го предмета = 5.

Вероятности таких предметов в сундуке считаются просто. Вероятность = вес предмета/сумма весов всех предметов. Соответственно, вероятности будут следующими: 1-й предмет = 2/10, 2-й предмет = 3/10, 3-й предмет = 5/10.

Веса удобно конфигурировать, когда предметы могут добавляться или удаляться из списка вариантов. Вам не нужно будет прописывать шансы каждого предмета заново. Шансы всегда считаются на основе имеющихся весов. Вам не нужно следить за тем, чтобы шансы всегда имели в сумме вероятность = 100%. Распределение происходит автоматически.

Суть задачи

В игре доступен ежедневный список миссий. Миссии выполняются последовательно.

Есть 3 варианта миссии. У каждого варианта есть свой вес.

Есть 2 слота в списке миссий. В каждый слот генерируется по миссии. Порядок слотов важен.

Одна и та же миссия, не может оказаться в разных слотах. То есть после того, как миссия помещается в слот, она исключается из списка вариантов.

Мы последовательно выбрали миссии для каждого слота на основе весов.

Какие шансы того, что во 2-м слоте окажется 1-й вариант миссии? Какие, в принципе, шансы у каждого из вариантов миссии оказаться в итоговом списке?

Скрипт

Скрипт написан на Lua и может быть запущен в любом онлайн-компиляторе Lua. Я добавил его сюда:

https://www.mycompiler.io/view/Hokc0FECLfc

Чтобы изменить скрипт нажмите на кнопку Fork.

В переменной WEIGHTS через запятую указываются веса миссий. Можете указать свои в любом количестве.

В CASES — количество генераций.

Скрипт выводит шансы вариантов по слотам. Легко заметить, что чем больше вес у 1-й миссии, тем ниже ее шанс оказаться во втором слоте (что логично, так как, она скорее, всего находится уже в первом слоте).

Также подсчитываются итоговые шансы вариантов оказаться в общем списке.

Тестируем на трех слотах, работает:

Скрипт на гитхабе:

https://gist.github.com/stiv-iv/8b0d409182c701b3da6b75cb923e3713