Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating Random Numbers for RPG games

I'm wondering if there is an algorithm to generate random numbers that most likely will be low in a range from min to max. For instance if you generate a random number between 1 and 100 it should most of the time be below 30 if you call the function with f(min: 1, max: 100, avg: 30), but if you call it with f(min: 1, max: 200, avg: 10) the most the average should be 10. A lot of games does this, but I simply can't find a way to do this with formula. Most of the examples I have seen uses a "drop table" or something like that.

I have come up with a fairly simple way to weight the outcome of a roll, but it is not very efficient and you don't have a lot of control over it

var pseudoRand = function(min, max, n) {
    if (n > 0) {
        return pseudoRand(min, Math.random() * (max - min) + min, n - 1)
    }

    return max;
}

rands = []
for (var i = 0; i < 20000; i++) {
    rands.push(pseudoRand(0, 100, 1))
}

avg = rands.reduce(function(x, y) { return x + y } ) / rands.length
console.log(avg); // ~50

The function simply picks a random number between min and max N times, where it for every iteration updates the max with the last roll. So if you call it with N = 2, and max = 100 then it must roll 100 two times in a row in order to return 100

I have looked at some distributions on wikipedia, but I don't quite understand them enough to know how I can control the min and max outputs etc.

Any help is very much welcomed

like image 210
chrs Avatar asked Jul 16 '16 13:07

chrs


People also ask

Is RNG good for games?

RNG definitely makes games fun. It's more of a neutral thing than a good or bad one, as it depends on how the developer uses it. The reason RNG makes things fun is that it introduces the element of surprise.

Is RNG really random?

Random number generators are typically software, pseudo random number generators. Their outputs are not truly random numbers. Instead they rely on algorithms to mimic the selection of a value to approximate true randomness.

What is RNG for gaming?

RNG is the acronym used for the term Random Number Generator, but there is so much more that goes on beneath the surface. RNG in video games is basically an algorithm that randomly decides a number value and implements it into the game when called for, which can change the course of a game drastically.

Is RNG lucky?

(4) Soft RNG Luck Examples: backgammon, most card games. RNG stands for “random number generator”. In the context of gaming, RNG refers to any situation in which an outcome is random.


2 Answers

A simple way to generate a random number with a given distribution is to pick a random number from a list where the numbers that should occur more often are repeated according with the desired distribution.

For example if you create a list [1,1,1,2,2,2,3,3,3,4] and pick a random index from 0 to 9 to select an element from that list you will get a number <4 with 90% probability.

Alternatively, using the distribution from the example above, generate an array [2,5,8,9] and pick a random integer from 0 to 9, if it's ≤2 (this will occur with 30% probability) then return 1, if it's >2 and ≤5 (this will also occur with 30% probability) return 2, etc.

Explained here: https://softwareengineering.stackexchange.com/a/150618

like image 91
user2314737 Avatar answered Oct 11 '22 13:10

user2314737


A probability distribution function is just a function that, when you put in a value X, will return the probability of getting that value X. A cumulative distribution function is the probability of getting a number less than or equal to X. A CDF is the integral of a PDF. A CDF is almost always a one-to-one function, so it almost always has an inverse.

To generate a PDF, plot the value on the x-axis and the probability on the y-axis. The sum (discrete) or integral (continuous) of all the probabilities should add up to 1. Find some function that models that equation correctly. To do this, you may have to look up some PDFs.

Basic Algorithm

https://en.wikipedia.org/wiki/Inverse_transform_sampling

This algorithm is based off of Inverse Transform Sampling. The idea behind ITS is that you are randomly picking a value on the y-axis of the CDF and finding the x-value it corresponds to. This makes sense because the more likely a value is to be randomly selected, the more "space" it will take up on the y-axis of the CDF.

  1. Come up with some probability distribution formula. For instance, if you want it so that as the numbers get higher the odds of them being chosen increases, you could use something like f(x)=x or f(x)=x^2. If you want something that bulges in the middle, you could use the Gaussian Distribution or 1/(1+x^2). If you want a bounded formula, you can use the Beta Distribution or the Kumaraswamy Distribution.
  2. Integrate the PDF to get the Cumulative Distribution Function.
  3. Find the inverse of the CDF.
  4. Generate a random number and plug it into the inverse of the CDF.
  5. Multiply that result by (max-min) and then add min
  6. Round the result to the nearest integer.

Steps 1 to 3 are things you have to hard code into the game. The only way around it for any PDF is to solve for the shape parameters of that correspond to its mean and holds to the constraints on what you want the shape parameters to be. If you want to use the Kumaraswamy Distribution, you will set it so that the shape parameters a and b are always greater than one.

I would suggest using the Kumaraswamy Distribution because it is bounded and it has a very nice closed form and closed form inverse. It only has two parameters, a and b, and it is extremely flexible, as it can model many different scenarios, including polynomial behavior, bell curve behavior, and a basin-like behavior that has a peak at both edges. Also, modeling isn't too hard with this function. The higher the shape parameter b is, the more tilted it will be to the left, and the higher the shape parameter a is, the more tilted it will be to the right. If a and b are both less than one, the distribution will look like a trough or basin. If a or b is equal to one, the distribution will be a polynomial that does not change concavity from 0 to 1. If both a and b equal one, the distribution is a straight line. If a and b are greater than one, than the function will look like a bell curve. The best thing you can do to learn this is to actually graph these functions or just run the Inverse Transform Sampling algorithm.

https://en.wikipedia.org/wiki/Kumaraswamy_distribution

For instance, if I want to have a probability distribution shaped like this with a=2 and b=5 going from 0 to 100:

https://www.wolframalpha.com/input/?i=2*5*x%5E(2-1)*(1-x%5E2)%5E(5-1)+from+x%3D0+to+x%3D1

Its CDF would be:

CDF(x)=1-(1-x^2)^5

Its inverse would be:

CDF^-1(x)=(1-(1-x)^(1/5))^(1/2)

The General Inverse of the Kumaraswamy Distribution is: CDF^-1(x)=(1-(1-x)^(1/b))^(1/a)

I would then generate a number from 0 to 1, put it into the CDF^-1(x), and multiply the result by 100.

Pros

  • Very accurate
  • Continuous, not discreet
  • Uses one formula and very little space
  • Gives you a lot of control over exactly how the randomness is spread out
  • Many of these formulas have CDFs with inverses of some sort
  • There are ways to bound the functions on both ends. For instance, the Kumaraswamy Distribution is bounded from 0 to 1, so you just input a float between zero and one, then multiply the result by (max-min) and add min. The Beta Distribution is bounded differently based on what values you pass into it. For something like PDF(x)=x, the CDF(x)=(x^2)/2, so you can generate a random value from CDF(0) to CDF(max-min).

Cons

  • You need to come up with the exact distributions and their shapes you plan on using
  • Every single general formula you plan on using needs to be hard coded into the game. In other words, you can program the general Kumaraswamy Distribution into the game and have a function that generates random numbers based on the distribution and its parameters, a and b, but not a function that generates a distribution for you based on the average. If you wanted to use Distribution x, you would have to find out what values of a and b best fit the data you want to see and hard code those values into the game.
like image 37
AlgorithmsX Avatar answered Oct 11 '22 13:10

AlgorithmsX