Napisałem do tego kod . Istotą tego jest używanie statystyk do korygowania pechowych serii. Możesz to zrobić, aby śledzić, ile razy zdarzenie miało miejsce, i użyć go do odchylenia liczby wygenerowanej przez PRNG.
Po pierwsze, w jaki sposób śledzimy procent zdarzeń? Naiwnym sposobem na to byłoby zachowanie wszystkich liczb kiedykolwiek wygenerowanych w pamięci i uśrednienie ich: co by działało, ale jest okropnie nieefektywne. Po krótkiej refleksji wpadłem na następujące (które są w zasadzie skumulowaną średnią ruchomą ).
Weź następujące próbki PRNG (gdzie wykonujemy, jeśli próbka jest> = 0,5):
Values: 0.1, 0.5, 0.9, 0.4, 0.8
Events: 0 , 1 , 1 , 0 , 1
Percentage: 60%
Zauważ, że każda wartość przyczynia się do 1/5 wyniku końcowego. Spójrzmy na to z innej strony:
Values: 0.1, 0.5
Events: 0 , 1
Zauważ, że 0
przyczynia się do 50% wartości i 1
przyczynia się do 50% wartości. Posunięto się nieco dalej:
Values: [0.1, 0.5], 0.9
Events: [0 , 1 ], 1
Teraz pierwsze wartości stanowią 66% wartości, a ostatnie 33%. Możemy zasadniczo sprowadzić to do następującego procesu:
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
Teraz musimy przesunąć wynik wartości próbkowanej z PRNG, ponieważ wybieramy procentową szansę, tutaj rzeczy są znacznie łatwiejsze (w porównaniu z, powiedzmy, losowymi wielkościami obrażeń w RTS). Trudno to wytłumaczyć, ponieważ „przyszło mi to do głowy”. Jeśli średnia jest niższa, oznacza to, że musimy zwiększyć szansę wystąpienia zdarzenia i odwrotnie. Oto kilka przykładów
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%
Teraz „przyszło mi do głowy”, że w pierwszym przykładzie 83% było po prostu „0,5 z 0,6” (innymi słowy „0,5 z 0,5 plus 0,1”). W przypadku zdarzeń losowych oznacza to:
procced = (sample * 0.6) > 0.1
// or
procced = (sample * 0.6) <= 0.5
Aby wygenerować zdarzenie, należy zasadniczo użyć następującego kodu:
total = average + desired
sample = rng_sample() * total // where the RNG provides a value between 0 and 1
procced = sample <= desired
I dlatego dostajesz kod, który wpisałem w sedno. Jestem prawie pewien, że wszystko to można wykorzystać w scenariuszu przypadkowego uszkodzenia, ale nie poświęciłem czasu, aby to rozgryźć.
Oświadczenie: To są wszystkie statystyki domowe, nie mam wykształcenia w tej dziedzinie. Moje testy jednostkowe jednak zdają.