Events with different probability

Hello everyone! So im currently need to implement system that generated events with different chances to appear, like give reward(30%), deal damage to player (15%),do nothing(5%).

I know in c# there are awesome feature as delegates and im using them for this. Implementins this is easy for me, i have another trouble. How should my system work?

Searching the web i found one solution:

1)Random value from (0 to 1) * 100 - that will out dice roll.

2)Sort our array from the smallest chance to biggest(like 5,35,60,76 etc).

3)Then loop this array and if(randomedChance is smaller than eventChance) - than do this event.

87195-vbar-e20693c.png

For example, 0 - 5 chances will bless player, 6 - 15 will curse player, 16 - 25 will give potion, 25 - 45 will do nothing.

But if there will be 5 events wil 20 percentage to appear. It will always be the same event. How to avoid this?

Is this a good solution? And are there any other ways to implement this?

Thanks in advance.

Like Glurth indirectly already mentioned your approach doesn’t represent the actual percentage values you might want. I answered a similar question just a few days ago.

If you have several percentages they all need to add up to the max value (in case of percentages to 100). If they don’t the result has nothing to do with actual percentages. Also it’s logically not possible to have say 6 events each with a chance of 20%. Those would add up to 120%. If you properly normalize the “weights” you get the actual percentages.

pNormalized = p*100 / sum;

So each of the 6 events would have an effective chance of 16.666% (16 + 2/3). 20 * 100/120 == 16.666

If you “overlap” your percentage values, the overlapping area is effectively subtracted from later elements. So in your example case “bless player” has a chance of 5%. However “curse player” as well as “give potion” has only an effective chance of 10% each. “Do nothing” has a chance of 20%. And there’s still the unaccounted “rest” of 55% where actually no of your options is choosen. It’s misleading to use the values in this way as you don’t really see the actual likeliness of each event.

Even when you “queue” up your values like Glurth said you still have 10% left over as your values add up to “90”, not 100. Maybe “Do nothing” should have 55%?

As i said in my other answer you can either add up all “weights” and roll a number between 0 and the sum of all weights. Each weight does not represent a percentage in this case but a “relative likeliness”. If you add more events the likeliness of the existing events will decrease as you have to distribute your “100%” to all events. If there are more events, each event has to be less likely.

This of course assumes that you want to pick a single event.

There is a simple implementation of a WeightedRandomizer on the wiki which does exactly that.

You should make yourself clear what kind of behaviour you need / want.

(Personally, I think Bunny83’s answer is “more complete”)

1,2,3 seems like a good way to do that. Just make sure you loop in the right order for your comparisons,

To distribute your individual probabilities across the full range of 0 to 100, you will want to add each individual chance, to the “end” of the previous range. e.g.

-Event A 5% chance: range (0 to 5)

-Event B 10% chance range (0+5 to 5+10)

-Event C 12% chance: range (0+5+10 to 5+10+12)

Note that with this method, you don’t actually need to have a sorted array, since it’s the range between the two event’s you are effectively checking.

Hexagonius made an excellent suggestion to modify this:

I would do it like this:

  • add all probabilities together. - generate a random value between 0 and the sum (which is nothing else than 100%)

  • loop through your probabilities while adding them up. when the sum is larger than your random value, that’s the event to pick.