# Non equi-probable random function

I was trying to find or make a function which is not equi-probable, meaning some values are less probable than others. Apparently what I want has something to deal with http://en.wikipedia.org/wiki/Normal_distribution and Gaussian Distributions.

The math and algorithmics involved in such a function seemed a little complex, and I was not sure if they were really necessary.

My goal is to make better loot more rare to get (the player can generate an infinite amount of loot events), but since I want the loot quality to be expressed with a single value, I need a function that returns values > 0.9 very rarely but will return value > 0.1 much more often.

I tried log((100*random())^(0.01*random())) ('^' meaning exponent, so '**' to be precise) in python, I got results that seems pretty satisfying, but I'm really suspicious that I can can trust those results.

Is there some type of standard function that already do what I'm looking for ? Do you think this formula is somehow reliable ?

I don't want to have "loot tables" because they're integral values, and it would require more tweaking, and I don't intend to have special items that are much more powerful than lower tier items.

Here are the results, with 10000 picks:

('0.003', 1514, '15%', '####################')
('0.006', 1323, '13%', '#################')
('0.010', 1269, '12%', '################')
('0.014', 1169, '11%', '###############')
('0.022', 1187, '11%', '###############')
('0.027', 1089, '10%', '##############')
('0.028', 964, '9%', '############')
('0.034', 760, '7%', '##########')
('0.037', 496, '4%', '######')
('0.043', 228, '2%', '###')

• log(a)^b = b*log(a), so maybe you can save some performance. – skind Apr 28 '15 at 15:52

## 3 Answers

Here is my gaussian distrib. in 0..1 in c# With reference Note: r is the Random class istance.

   private double  nextGaussian(double mean,double variance ) {
// http://stackoverflow.com/questions/218060/random-gaussian-variables
//with mean = 0.5 and variance = 0.5 we get uniform distribution over [0..1]
double u1 = r.NextDouble(); //these are uniform(0,1) random doubles
double u2 = r.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal =
mean + variance * randStdNormal; //random normal(mean,stdDev^2)
return randNormal;
}


I don't understand phython but a simple but not very flexible solution is to use annidated if like this one:

float ProbDensityFunction ()
{
value = random();
if (value > .1)
value = random();
else if (value > .2)
value = random();
...
else if (random()>.9)
value = random();

return value;
}


In this way you have a probability density function where low values have the most chance to be selected.. the drowback is that is not flexible but you can change the values of conditions or increase/decrease the number of "if" to obtain the desired function.

How about a trivial power function? Take a random number in the 0 to 1 interval, raise it to the power "needed". This is easy to calculate and different selections of exponent will give you the loot-rarity you want.

• No, because all those picks are equiprobable. I had this idea at first, but when you do stats on it, if you call that function 1000 times, and look at how it distributes, it's odd results. – jokoon Apr 29 '15 at 16:07