J'ai en fait écrit du code pour le faire . L'essentiel est d'utiliser des statistiques pour corriger les séquences malchanceuses. Pour ce faire, vous pouvez suivre le nombre de fois où l'événement s'est produit et l'utiliser pour biaiser le nombre généré par le PRNG.
Premièrement, comment pouvons-nous suivre le pourcentage d'événements? La manière naïve de le faire serait de conserver tous les nombres jamais générés en mémoire et de les faire la moyenne: ce qui fonctionnerait mais est horriblement inefficace. Après un peu de réflexion, j'ai trouvé ce qui suit (qui est essentiellement une moyenne mobile cumulative ).
Prenez les échantillons PRNG suivants (où nous procédons si l'échantillon est> = 0,5):
Values: 0.1, 0.5, 0.9, 0.4, 0.8
Events: 0 , 1 , 1 , 0 , 1
Percentage: 60%
Notez que chaque valeur contribue à 1/5 du résultat final. Regardons les choses autrement:
Values: 0.1, 0.5
Events: 0 , 1
Notez que le 0
contribue à 50% de la valeur et le 1
contribue à 50% de la valeur. Un peu plus loin:
Values: [0.1, 0.5], 0.9
Events: [0 , 1 ], 1
Maintenant, les premières valeurs contribuent à 66% de la valeur et les 33 derniers%. Nous pouvons essentiellement résumer cela jusqu'au processus suivant:
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
Maintenant, nous devons biaiser le résultat de la valeur échantillonnée à partir du PRNG, parce que nous allons chercher un pourcentage de chance ici, les choses sont beaucoup plus faciles (contre, disons, des quantités aléatoires de dommages dans un RTS). Cela va être difficile à expliquer parce que cela vient de «me venir à l'esprit». Si la moyenne est inférieure, cela signifie que nous devons augmenter les chances que l'événement se produise et vice-versa. Donc, quelques exemples
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%
Maintenant, ce qui m'est venu à l'esprit, c'est que dans le premier exemple, 83% n'était que "0,5 sur 0,6" (en d'autres termes "0,5 sur 0,5 plus 0,1"). En termes d'événements aléatoires, cela signifie soit:
procced = (sample * 0.6) > 0.1
// or
procced = (sample * 0.6) <= 0.5
Donc, pour générer un événement, vous utiliseriez essentiellement le code suivant:
total = average + desired
sample = rng_sample() * total // where the RNG provides a value between 0 and 1
procced = sample <= desired
Et donc vous obtenez le code que j'ai mis dans l'essentiel. Je suis presque sûr que tout cela peut être utilisé dans le scénario de dommages aléatoires, mais je n'ai pas pris le temps de le comprendre.
Avertissement: Ce sont toutes des statistiques locales, je n'ai aucune formation dans le domaine. Mes tests unitaires réussissent cependant.