Я фактично написав якийсь код, щоб це зробити . Суть її полягає у використанні статистики для виправлення нещасливих смуг. Як ви можете це зробити - це відслідковувати, скільки разів відбулася подія, і використовувати це для зміщення кількості, створеного PRNG.
По-перше, як ми відстежуємо відсоток подій? Наївним способом цього було б зберегти всі колись створені в пам'яті цифри і порівняти їх: це могло б працювати, але жахливо неефективно. Трохи поміркувавши, я придумав наступне (що в основному є кумулятивною середньою середньою ).
Візьміть такі зразки PRNG (де ми пропонуємо, якщо зразок> = 0,5):
Values: 0.1, 0.5, 0.9, 0.4, 0.8
Events: 0 , 1 , 1 , 0 , 1
Percentage: 60%
Зауважте, що кожне значення сприяє 1/5 кінцевого результату. Давайте розглянемо це по-іншому:
Values: 0.1, 0.5
Events: 0 , 1
Зауважте, що це 0
вносить 50% вартості, а 1
50% вартості. Зроблено трохи далі:
Values: [0.1, 0.5], 0.9
Events: [0 , 1 ], 1
Зараз перші значення вносять 66% від вартості, а останні 33%. Ми в основному можемо це перенаправити до наступного процесу:
result = // 0 or 1 depending on the result of the event that was just generated
new_samples = samples + 1
average = (average * samples / new_samples) + (result * 1 / new_samples)
// Essentially:
average = (average * samples / new_samples) + (result / new_samples)
// You might want to limit this to, say, 100.
// Leaving it to carry on increasing can lead to unfairness
// if the game draws on forever.
samples = new_samples
Тепер нам потрібно змістити результат відбору вартості з PRNG, оскільки ми збираємось на відсотковий шанс, тут справи набагато простіші (порівняно, скажімо, випадкові суми збитків у RTS). Це буде важко пояснити, оскільки це мені просто прийшло в голову. Якщо середній показник нижчий, це означає, що нам потрібно збільшити шанс події, яка відбудеться, і навпаки. Отож кілька прикладів
average = 0.1
desired = 0.5
corrected_chance = 83%
average = 0.2
desired = 0.5
corrected_chance = 71%
average = 0.5
desired = 0.5
corrected_change = 50%
Тепер "мені прийшло в голову" те, що в першому прикладі 83% було лише "0,5 з 0,6" (іншими словами "0,5 з 0,5 плюс 0,1"). У термінах випадкових подій це означає:
procced = (sample * 0.6) > 0.1
// or
procced = (sample * 0.6) <= 0.5
Отже, щоб генерувати подію, ви в основному використовуєте наступний код:
total = average + desired
sample = rng_sample() * total // where the RNG provides a value between 0 and 1
procced = sample <= desired
І тому ви отримуєте код, який я вклав у суть. Я впевнений, що це все можна використати в сценарії випадкових випадків пошкодження, але я не знайшов часу, щоб це зрозуміти.
Застереження: Це все домашня статистика, я не маю освіти в цій галузі. Мої одиничні тести все ж проходять.