Как стать автором
Обновить

Комментарии 33

Помнится среднее из трёх случайных чисел высмеивалось как пример г-нокода с комментариями вроде «true random». А тут даже его применение описано.


Хороший анализ, но вы верно подметили, что зачастую имеет место быть схожая проблема.


Как видим, в итоге ничего общего с вероятностью 1 к 10000, но для целей геймплея этого, возможно, было достаточно. Хотя больше похоже на ненамеренное сокрытие реальных вероятностей от самого разработчика, что может приводить к неправильным решениям в будущих доработках программы.

Ещё у меня есть предположение, что часть подобных генераторов случайных чисел имеют определённые уязвимости, которые можно использовать. К примеру если при промахах повышается вероятность, то возможны ситуации стрельбы со слабого оружия/способности для набивания промахов, чтобы потом попасть сильным оружием/способностью с повышенной вероятностью.

К примеру если при промахах повышается вероятность, то возможны ситуации стрельбы со слабого оружия/способности для набивания промахов, чтобы потом попасть сильным оружием/способностью с повышенной вероятностью.

Это, впрочем, может быть и самостоятельной игровой механикой.
Другое дело, что в мультиплеерных играх это плохое решение.
Вроде в HOMM 5 была такая тема (я в комментарии к прошлой статье уже писал про нее). Призраки имеют большой (вроде 50% или около того) шанс уклониться от атаки, поэтому убивать их бывает очень сложно. Но разработчики предусмотрели, что не может быть трех промахов подряд, после двух промахов третий удар гарантированно попадает. Игроки им пользуются — сперва бьют призраков множеством слабых отрядов, дожидаются двух промахов подряд, а затем вкатывают им гарантированный урон от своего основного отряда.
Ага. Я поэтому очень удивился, когда промахнулся в третий раз однажды. Правда, на игре стояли моды, но таки это всё равно был единственный случай за долгие годы практики в HoMM V
Ну что вы! True random это
return(4); //chosen by fair dice roll
           //guaranteed to be random
А казалось бы — да что тут сложного. На первый взгляд…

Скажите, пожалуйста, а почему не используют, скажем, медиану от 5-10 рандомных значений? Это должно быть крайне близко к истине. И не сложно.
Я не понял, какого результата Вы хотите достичь, применяя медиану для 10 значений?
Случайное число ведь генерируется в диапазоне 1..100 (или больший диапазон, если надо избавиться от ошибок малых чисел).
А при использовании медианы будет получена просто случайное число, которому «посчастливилось» выпасть больше 1 раза.
Может я неправильно Вас понял.
https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B4%D0%B8%D0%B0%D0%BD%D0%B0_(%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0)

Попробовал набросать немного кода. После 20 минут понял что первый абзац в моем комментарии выше надо умножить еще на 10. Как минимум. :)

Потом начал думать что рандом не так уж и плохо. При шансе 60% попасть 1 раз из 10 можно. Кто знаком с теорией вероятностей понимает, что это нормально. Всякое бывает. Конечно, не уверен что для игры это хорошо.

Накидал просто скрипт на PHP. Поставил в конфиге 1000 подходов по 10 повторений, вероятность попасть 60%, результаты:

Array
(
[1] => 1
[2] => 13
[3] => 30
[9] => 45
[4] => 99
[8] => 121
[5] => 202
[7] => 231
[6] => 258
)
9

Указано: [попаданий из 10 раз] => количество событий (из 1000 подходов), в конце — это максимум попаданий подряд (т.е. был случай, или несколько, когда в подходе из 10 ударов при вероятности попасть 60% было 9 попаданий подряд).

В принципе, не все так плохо с чистым рандомом. Мы видим что диапазон 5-7 попаданий занимает: ((202 + 231 + 258) / 1000) * 100 = 69,1% всех случаев. 8 и 4 попаданий случаются примерно в 1 из 10 подходов по 10 ударов. Т.е. достаточно редко. Бывает и круто повезло (8), и не твой день (4). 9 раз удалось попасть лишь в 4,5% случаев. 10 раз ни разу. 2 раза — 1,3% и 1 раз попали в 1 из 1000 подходов по 10 ударов.

А вот то же самое для 15%:

Array
(
[5] => 3
[4] => 55
[3] => 134
[0] => 185
[2] => 286
[1] => 337
)
3

Больше 5 раз попасть не удалось, и то это случилось лишь в 3 из 1000 подходов. 95% лежат в пределах от 0 до 3 попаданий.

Конечно, математика математикой, но тут надо брать реальную игру и проводить плей тесты. Я вполне согласен с тем, что при вероятности попасть 60% игроки будут ожидать попасть 6 раз из 10 ударов. А это, судя по всему, красиво сделать можно только проводя коррекцию новых значений на основе данных от предыдущих попыток. Впрочем, и чистый рандом, когда игрок иногда может попасть очень много или очень мало, тоже выглядит весьма интересно. Как по мне.
Мне нравится интуитивный подход к гарантированной вероятности. (60% = 6 из 10).

Я бы реализовывал (в контексте «из 100») таким образом: вероятности генерируются заранее (последовательность рандома), как 60 «да» и 40 «нет», а дальше эта последовательность shuffle. Каждый следующий берёт элемент из этого пула. Спустя 100 ходов будет точно 60 «да» и точно 40 «нет». В принципе, для уменьшения предсказуемости, можно менять размер пула (100, 200, 300) случайным образом. Но всё время поддерживать рандомную справедливость на ограниченном окне бросков.
Тоже хороший вариант. Не для всех случаев, но для логических/тактических может быть хорошим решением.
А вы его не можете проанализировать? Насколько оно от реального рандома будет отклоняться?
Ну так ведь отклонение будет в размере статистической погрешности. На бесконечном отрезке отклонений не будет (это если генератор псевдослучайных чисел не кривой, что иногда бывает).
… надо посмотреть, какая вероятность худшего случая, т.е. когда на предыдущей генерации было «все 60 да вначале пула», а на следующей «все 60 в конце пула» и образовалась «долина невезения» из «80 ходов нет».
посмотрел на графики — чем-то на индекс Джини из статьи про "теорию счастья" походит.
Только там вероятности событий нельзя напрямую в генераторе «подкрутить»…
Когда говорят о подкрученной вероятности надо упомянуть пример псевдослучайности в таких играх, как Warcraft 3, League of Legend, Dota 2 и других, где итоговая вероятность после изменений остаётся неизменной, хотя на самом деле вероятность получить большие серии успехов/неудач заметно меньше, чем при полной случайности. Здесь описание реализации в Доте (вероятность успеха после успеха заметно меньше, чем заявлено, и после каждой неудачи растет, обычно линейно, пока не достигает 1). В большинстве методов из статьи этот подход можно тоже применить, решая уравнение, так что доля успехов соответствовала названной вероятности. Это особенно важно для онлайн игр, так как там серия критов/уворотов может решить исход схватки.
Я бы не назвал вариант из доты хорошим. Судя по таблице работает неплохо это только для первых 20%, а дальше накапливается ошибка не в пользу игрока. Ещё одна вещь, которая не нравится, что наиболее вероятное N не всегда равно 1 / P. Хотя сама идея хорошая, просто надо лучше подстроить формулу.

И насколько мне известно в Warcraft 3 такой механики не было.
Просто считать надо точнее. Не знаю почему в доте так (погрешность для больших вероятностей), но там ссылку легче искать. В Warcraft 3 это работало для критов, уворотов и оглушения и подобных способностей, эта задача была решена для всех вероятностей кратных 5% (то есть все числа были уже в движке). Это кстати вызывало любопытную особенность — в редакторе можно было ставить вероятность кратную 1%, но она округлялась до ближайших 5%, и соответственно 1% становился 0… Конечно можно было использовать скрипты со своей реализацией случайности, но всё в игре работало по такому правилу, все разные источники работали независимо друг от друга. А в игре 1% от 0 легко не отличить. Эта механика перешла и в другие игры. И одно из развлечений в таких играх — проверка работы РНГ.

Вспомнил про округление до кратных 5, точно, спасибо, память подвела. Её не было при использовании скриптованных способностей, что логично. А в стандартных была.


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


Вообще идея хорошая и легкореализуемая, но я не согласен (с информацией из статей), что на практике сложно использовать знания о таком рандоме, особенно в случае защитной способности.

В доту2 их перенесли с изменениями, исправив искривление после 20%. Считается, что искривление было вызвано тем, что в варкрафте была всего пара абилок с вероятностью выше 20%, поэтому разработчики не запаривались с точностью более высоких шансов, создав гигантское расхождение на высоких значениях.
В ноль не округлялось, бралось как 5%. В древних версиях доты был хаос кнайт с 1% шанса крита на 11х, и оно работало. Не думаю, что тогда были подкованные знатоки, которые бы подсказали вписать в подсказку 1%, а в данные 5%.
В Вики написано, что не работало. Я уже застал время (версии с 6.32 видел), когда все эти вероятности были кратными 5%, картоделы уже знали об этой фиче. Абсолютно уверенным быть не могу, не тестировал.
Верно, моя ошибка. Глянул еще раз на алгоритм, там не было защиты от подобного. Брался шанс и
floor(chance * 0.2 + 0.5)
для поиска по таблице вероятностей, к 5% попадали только шансы 2.5% и выше
Мне нравится такой вариант (используется в некоторых играх). Такой метод гарантирует стабильность (если попадание 80% то из 10 ударов 8 попадут).

Предположим у нас вероятность попадания 40%. В начале мы генерируем число [0,100).
При каждой проверке при прибавляем к числу вероятность попадания. Если число больше 100, то мы попали, вычитаем 100. Число 100 взято для целочисленных процентов, если проценты дробные, то вы поняли. Можно и дробное [0,1) генерировать.

Пример:
0. начальное значение — 50.
1. 50+40 = 90 < 100 -> промах
2. 90+40=130 > 100 -> попадание -> число 30
3. 30+40 = 70 < 100 -> промах
4. 70+40=110 > 100 -> попадание -> число 10.

Таким образом у нас при вероятности в 40% никогда не будет 2 попаданий подряд, и при этом из 3 хотя бы 1 попадёт.
В этом есть смысл, но
Таким образом у нас при вероятности в 40% никогда не будет 2 попаданий подряд

Очень многим будет казаться пресным и неестественным. Тут должна быть вся механика на это настроена.
И тогда игрок будет использовать каждый второй удар в свою пользу. Ну или какой-то там другой в зависимости от вероятности.
Согласен, но ничего не злит больше, чем получение 2-3 ударов подряд при 50% уклонения. Из-за этого, при наличии условных вариантов увеличить уклонение и увеличить защиту, уклонение слишком большой риск. Подобная равномерность позволяет сбалансировать. Безусловно это подойдёт не любой игре. (механика используется в PoE если интересно).
Согласен, эмоции это вызывает негативные, но нужно понимать, когда какая механика эффективнее.

Уклонение имеет преимущество, когда урон неравномерный и есть источники, блокировка которых полностью выгоднее, чем просто уменьшение урона(ну или там какой-то эффект, который не пройдёт, к примеру оглушение).

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

В общем случае они должны быть равны при прочих равных.

Но в общем случае защита более предсказуема, уклонение даёт вероятность победить там, где с защитой точно нельзя. Выбрать вариант с меньшей дисперсией(то есть защиту) вполне рациональное решение в большинстве случаев.
НЛО прилетело и опубликовало эту надпись здесь
Согласен. Но в большинстве случаев даже если раскрыть формулу, то её смысл поймут далеко не все игроки. Поэтому, мне кажется, и возникла это статья, как сделать формулу так, чтобы тот который не понимает формулы не сильно потом жаловался на форуме (упрощённо). А по поводу пое так не сильно исключений много видел, там просто механикам усложнялась от патча к патчу, появлялись удачливые шансы и прочее, но это уже оффтоп по большому счёту.
НЛО прилетело и опубликовало эту надпись здесь
Какие-то вероятности без учета расстояния это несусветно. Даже во времена UFO1 выглядело как «результат г-кода».
Не путайте мух с котлетами. Расстояние — один из множества факторов, который может влиять на меткость. Еще это может быть усталость, окружающая обстановка, состояние экипировки, навыки персонажа, умения противника, и еще миллион с тележкой факторов.

Речь не об определении числового % вероятности попасть. А о реализации алгоритма расчета самого события на основе этой вероятности. Или даже цепочки таких событий.

Так мило смотреть, как в сообществе разработчиков витает идея, которая вот-вот должна сформироваться в последовательную научную теорию :)


"Честную случайность" можно формализовать как квазислучайную последовательность. Такие последовательности могут проходить тесты на случайность, но заполняют область значений "более равномерно", что может быть полезно для эффективного численного интегрирования и прочих Монте-Карло штук.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации