# Algorithm for determining random events [duplicate]

I'm struggling with coming up with an elegant solution to generating random events in the game that I'm working on.

Say there are 4 classes of events that can happen, with varying events in those classes that may occur.

So something along the lines of

main_events = {"common event", "not so common event", "somewhat rare event", "rare event"}
sub_events[0] = {"common event 1", "common event 2",..}
...


I have a somewhat kludgey solution in place that first just has a random number generated between 0 and 100, and if the number falls within a given range then a main event will be triggered. Then I'll do another random roll to see which sub event occurs.

Is there a better solution than something along these lines? Like I mention, it doesn't feel very elegant, and I'd like to make it easily expandable for the addition of future events.

## marked as duplicate by Philipp, DMGregory♦Aug 23 at 13:49

• better in what way? it seems expandable enough if you want more events just add to the sub events or main events arrays. The only improvment to make it easier to expand would be possibly reading the events and sub-events in from a file so you don't have to recompile if you change the rarity of an event. – lathomas64 Nov 29 '10 at 17:57
• moreso that this was my initial take on the issue, and my guess was that there is a better or more elegant way of handling the generation of random events – the_e Nov 29 '10 at 18:09
• I see nothing wrong with this approach, I used a similar method for determining probabilities when building a random maze. – Bryan Harrington Dec 8 '10 at 5:42

(This is based on my answer for a similar question on Stack Overflow.)

It sounds like you're asking for a more flexible way of specifying the probability of each event. For that, you can use a simple weighing algorithm: simply decide how common each event should be and assign it a weight that is appropriate compared to the other weights. For example, if you have events A, B and C, with probabilities 70%, 25% and 5%, you could give them the weights 70, 25 and 5 (or 14, 5, and 1 - the important thing is the relative difference).

Once you have that, you can use the following algorithm to select an event:

Given a list L of items (I,W), where I is the item and W is the weight:

1. Add all of the weights together. Call this sum S.
2. Generate a random number between 0 and S (excluding S, but including 0). Call this value R.
3. Initialize a variable to 0 to keep track of the running total. We'll call this T.
4. For each item (I,W) in L:
1. T=T+W
2. If T > R, return I.

It's up to you if you want to first select between the different groups of events, or if you want a single table with all of the events (where each "group" has an appropriate sum compared to the others).

Michael's solution is perfect if you want a single table of possible events.

Let's say you want to build a random insult generator, though. In this case, a series of tables would work best. You'd start with a table that has a list of general patterns. For example,

Your [RELATIVE] [RELATION] [ANIMAL]!
Go [VERB] [NOUN] in your [ORIFICE]!


Now say the random generator picks the second pattern. You call the verb table, which has entries like:

stick
jam
shove


But here's where it gets interesting, your noun table might look like

[ANIMAL]


So you see, in this manner you can generate sophisticated and complex results.

As for actually implementing something like this, here's an example of how you might do it in JavaScript.

function Noun() {
var items = 3;
var i = Math.floor(Math.random()*items);
switch (i)
case 0:
return Animal();
break;
case 1:
break;
case 2: