Quite often when developing a game I need “random” numbers, that I can reproduce or that I can steer. Why? – For example when setting up a level or when resetting a level you might want to have it look random, but still the same every time you load it. – So how do we do that? There are tons of ways of achieving a so called “seeded random generated number” – if you want any details on the algorithms you can for example check out this link. But basically they all work the same: You initialize the algorithm with a “seed” (a number, that you choose to steer the algorithm). And every seed will return its own unique set of “random” numbers, so e.g.: Every time I seed the Number 6, I get the same set of generated “random” numbers. Every time I seed the Number 10, I get the same set of “random” number, that is different from the set ‘6’ and so on…

Because of this fact: seeded random numbers are predictable, which is not bad, but just don’t use it for encryption purposes ect…

## The algorithm

So the algorithm I’m using is the following, it’s really very simple:

(this is nothing new and also nothing I invented, but I think this might help quite a few people)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// the initial seed Math.seed = 6; // in order to work 'Math.seed' must NOT be undefined, // so in any case, you HAVE to provide a Math.seed Math.seededRandom = function(max, min) { max = max || 1; min = min || 0; Math.seed = (Math.seed * 9301 + 49297) % 233280; var rnd = Math.seed / 233280; return min + rnd * (max - min); } |

You may ask: **Why ‘(seed * 9301 + 49297) % 233280‘ ?!**

The answer is both simple&complicated: The combination of 9301, 49297 and 233280 provide a very even distributed set of “random” numbers. Please don’t ask WHY – that’s the complicated part, some very smart people figured out those numbers quite some time ago, and I also cannot tell you how they did it. But as allways: Google is your friend

## Benchmark

I set up a small benchmark on jsfiddle, to test the performance of that algorithm and also how the distribution of the generated sets are: Just hit then Run-button and see the results, for me Math.random() is usually 3-4x faster than Math.seededRandom(), which is for 100.000 numbers still within the range of 10-15ms and therefor pretty fast. Also the distribution of the numbers is very equal as you can see.

## See it in ‘action’

I quickly implemented this in my Runner Game Prototype, so no matter how often you reload the page, the level is allways going to look the same and all I did was replacing the “Math.random()” with “Math.seededRandom()” and of course I added the algorithmto the utilities-file.

If you want to try out other seeds, just go to: http://demos.indiegamr.com/jumpy/seededRandomLevel/?seed=1.57 and change the “seed” in the query string.

Pingback: 随机数生成算法 | 鹏博无际