В настоящее время я имею дело с многопользовательской боевой системой, в которой урон, наносимый игроками, всегда умножается на случайный коэффициент от 0,8 до 1,2.
Теоретически, действительно случайный ГСЧ может в конечном итоге давать одно и то же количество много раз (см. Дилемму Тетриса ). Это может привести к матчу, в котором игрок всегда наносит очень большой урон, а другой всегда наносит очень низкий урон.
Что я могу сделать, чтобы этого не случилось? Некоторые RNG лучше других избегают повторения?
algorithm
multiplayer
random
Пользователь не найден
источник
источник
Ответы:
Вы можете решить ее так же, как это делает Тетрис, составив заранее заданный список результатов урона и перетасовки.
Допустим, вы знаете, что игрок собирается нанести 0,8x-1,2x урона с линейным распределением. Возьмите список [0,8, 0,9, 1,0, 1,1, 1,2]. Перемешайте это случайно , так что вы получите, например, [1.2, 1.0, 0.8, 0.9, 1.1].
В первый раз игрок наносит урон, он наносит 1,2х. Тогда 1х. Затем и т. Д. До 1,1х. Только когда массив пуст, вы должны генерировать и перемешивать новый массив.
На практике вы, вероятно, захотите сделать это для 4+ массивов одновременно (например, начните с [0.8,0.8,0.8,0.8,0.9,0.9,0.9,0.9, ...]). В противном случае период последовательности достаточно мал, чтобы игроки могли выяснить, является ли их следующий удар «хорошим» или нет. (Хотя это также может добавить больше стратегии к бою, как, например, в таблице Hoimi Dragon Quest IX , в которой люди придумали, как исследовать, просматривая исцеляющие цифры и подправляя, пока вам не гарантировано редкое падение.)
источник
Я на самом деле написал код для этого . Суть его в том, чтобы использовать статистику для исправления неудачных полос. Вы можете сделать это, чтобы отследить, сколько раз произошло событие, и использовать это для смещения числа, сгенерированного PRNG.
Во-первых, как мы отслеживаем процент событий? Наивным способом сделать это было бы сохранить все числа, когда-либо созданные в памяти, и усреднить их: это сработало бы, но ужасно неэффективно. После недолгого размышления я придумал следующее (которое в основном является накопительной скользящей средней ).
Возьмите следующие образцы PRNG (где мы выполняем, если выборка> = 0.5):
Обратите внимание, что каждое значение вносит вклад в 1/5 конечного результата. Давайте посмотрим на это по-другому:
Обратите внимание, что
0
вклад составляет 50% стоимости, а1
вклад - 50% стоимости. Взятые чуть дальше:Теперь первые значения дают 66% стоимости, а последние 33%. Мы можем в основном отнести это к следующему процессу:
Теперь нам нужно сместить результат значения, отобранного из PRNG, потому что мы рассчитываем на процентный шанс, здесь все намного проще (по сравнению, скажем, со случайными величинами ущерба в RTS). Это будет трудно объяснить, потому что это «только что пришло мне в голову». Если среднее значение ниже, это означает, что нам нужно увеличить вероятность того, что событие произойдет, и наоборот. Итак, несколько примеров
Теперь «пришло мне в голову», что в первом примере 83% были просто «0,5 из 0,6» (другими словами «0,5 из 0,5 плюс 0,1»). В терминах случайного события это означает либо:
Таким образом, для генерации события вы должны использовать следующий код:
И поэтому вы получаете код, который я поместил в суть. Я почти уверен, что все это можно использовать в сценарии случайного повреждения, но я не потратил время, чтобы понять это.
Отказ от ответственности: Это все домашние статистические данные, у меня нет образования в этой области. Мои юнит-тесты все же проходят.
источник
samples
с самого начала инициализировать его максимальное значение (в данном случае 100). Таким образом, для стабилизации ГСЧ не требуется 99 итераций. В любом случае, я могу видеть один недостаток этого метода в том, что он не гарантирует справедливость, он просто обеспечивает постоянное среднее значение.total = (average / 2) + desired
.То, что вы просите, на самом деле является противоположностью большинства PRNG - нелинейное распределение. Просто добавьте в свои правила какую-то логику убывающей отдачи. Предполагая, что все, что выше 1,0х, является каким-то «критическим ударом», просто скажите, что каждый раунд ваши шансы получить крит увеличиваются на X, пока вы не получите один на в какой момент они сбрасываются до Y. Затем вы делаете два броска каждый раунд, один для определения критического или нет, а затем другой для фактической величины.
источник
Сид Майер выступил с великолепной речью на GDC 2010 именно об этой теме и играх Civilization. Я постараюсь найти и вставить ссылку позже. По сути, воспринимаемая случайность - это не то же самое, что истинная случайность. Чтобы все было честно, нужно проанализировать предыдущие результаты и обратить внимание на психологию игроков.
Избегайте полос неудачи любой ценой (если предыдущие два хода были неудачными, следующий должен быть гарантированно счастливым). Игрок должен быть всегда счастливее, чем искусственный противник.
источник
Используйте сдвиг
Общее распределение будет смещено по следующей формуле:
Возьмите это число и масштабируйте его до желаемого диапазона.
Каждый раз, когда игрок делает благоприятный бросок, вычитайте из предвзятости. Каждый раз, когда игрок катится неблагоприятно, добавьте к уклону. Измененная сумма может быть масштабирована в зависимости от того, насколько (не) благоприятен рулон или может быть фиксированная сумма (или комбинация). Вам нужно будет настроить конкретные значения, чтобы они соответствовали ощущениям, к которым вы стремитесь.
источник