{"id":181,"date":"2010-03-28T14:48:00","date_gmt":"2010-03-28T19:48:00","guid":{"rendered":"http:\/\/www.stephencalenderblog.com\/?p=181"},"modified":"2016-04-16T11:26:21","modified_gmt":"2016-04-16T16:26:21","slug":"better-random-number-generation-mersenne-twister-19937","status":"publish","type":"post","link":"https:\/\/www.stephencalenderblog.com\/?p=181","title":{"rendered":"Better Random Number Generation: Mersenne Twister 19937"},"content":{"rendered":"<p><a href=\"http:\/\/livedocs.adobe.com\/flash\/9.0\/ActionScriptLangRefV3\/Math.html#random%28%29\">Math.random()<\/a> is the bane of many Flash game developers, and in this article I am going to help you work around it (free code).<br \/>\n<!--more--><\/p>\n<p>So, Adobe will not release the methodology behind how their <a href=\"http:\/\/livedocs.adobe.com\/flash\/9.0\/ActionScriptLangRefV3\/Math.html#random%28%29\">Math.random()<\/a> function works:<br \/>\n\u201cReturns a pseudo-random number n, where 0 <= n < 1. The number returned is calculated in an undisclosed manner, and pseudo-random because the calculation inevitably contains some element of non-randomness.\u201d \u2013 from Adobe live docs as of the writing of this article.\n\nAll random number generators are pseudo-random, because they are all algorithmic in nature.  If you know the seed value and the algorithm, you can exactly predict the numbers the function will return.  In fact, the inability to seed the generator and repeat a string of \u2018random\u2019 numbers is a frustration of many people (usually not game developers, but there are plenty of practical applications that require it, cryptography for example).  \n\nThe other, more common problem, and the blight of every Flash dice game is that the <a href=\"http:\/\/livedocs.adobe.com\/flash\/9.0\/ActionScriptLangRefV3\/Math.html#random%28%29\">Math.random()<\/a> function tends to be \u2018streaky\u2019 or becomes \u2018stuck\u2019 on a number.  This is due to the <a href=\"http:\/\/livedocs.adobe.com\/flash\/9.0\/ActionScriptLangRefV3\/Math.html#random%28%29\">Math.random()<\/a> function deviating from a uniform distribution.  Statistically, and in as plain a language I can manage, you need to meet two criteria to qualify as a uniform distribution.  First, nearly even dispersal across the range.  In the case of a 6 sided die, if it was fair, and you rolled it 60 times, you would expect to see 1 through 6 represented equally \u2013 Flash\u2019s random number generator passes this test, but so would a die that roles 10 1s, then 10 2s, then 10 3s&#8230;  The second criteria deals with the probability of specific events happening, in the case of our 6 sided die example, rolling the same number 2 times in a row is 1\/6 * 1\/6 * 6  = 1\/6, there is a 1\/36 chance to roll any double, there are 6 pair of doubles (1s, 2s, etc.).  Odds of hitting any 3 streak is 1\/36.  Flash\u2019s problem is that these kinds of events happen at a higher frequency than they would in a true uniform distribution.<\/p>\n<p>Anyone that has written game engine code is familiar with the <a href=\"http:\/\/en.wikipedia.org\/wiki\/MT19937\">Mersenne Twister<\/a> routine, the Playstation 3 even made it its native random number generator.  While it has its critics, it has become widely adopted as the best (not to be read as fastest) number generator out there.  It has seen such wide adoption in games because it is the most cost effective, the best quality numbers for its speed.<\/p>\n<p>I\u2019m a math nerd, and I really enjoy the beauty of the number theory which I elaborate on here; but no one will judge you if you skip to the bottom and just steal the code.  Just remember to seed algorithm and that it returns a random unsigned integer i where 0 <= i < 0xFFFFFFFF = 4294967296.  \n\nThe <a href=\"http:\/\/en.wikipedia.org\/wiki\/MT19937\">Mersenne Twister<\/a> gets its name from the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mersenne_prime\">Mersenne primes<\/a> \u2013 all primes that are of the form: 2 to a power minus 1.  Often abbreviated as MT19937, the number part of the name comes from the length of the period: 2^19937 \u2013 1.  There are only 47 known <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mersenne_prime\">Mersenne Primes<\/a>, somewhat fantastically, 2147483647, or 2^31 \u2013 1, or the upper bound on a 32 bit integer is one as well.  There is a one-to-one relationship between <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mersenne_prime\">Mersenne Primes<\/a> and \u2018<a href=\"http:\/\/en.wikipedia.org\/wiki\/Perfect_number\">perfect numbers<\/a>\u2019 2^(p-1) * (2^p \u2013 1), which written in binary are all of the form p 1s followed by (p \u2013 1) zeros.  <a href=\"http:\/\/en.wikipedia.org\/wiki\/Perfect_number\">Perfect numbers<\/a> are not entirely relevant but just one of the things I discovered about <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mersenne_prime\">Mersenne Primes<\/a> and binary numbers that blew my mind, if you need more mind candy check out the connections between <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mersenne_prime\">Mersenne primes<\/a> and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Digital_root\">digital roots<\/a>, and the relationship between <a href=\"http:\/\/en.wikipedia.org\/wiki\/Perfect_number\">perfect<\/a> and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Triangular_number\">triangular numbers<\/a>. <\/p>\n<p>The prime for the <a href=\"http:\/\/en.wikipedia.org\/wiki\/MT19937\">Mersenne Twister<\/a> is often written as 2^(nw &#8211; r) \u2013 1 to clarify coefficients used in the algorithm.  The values for n, w, and r are 32, 624, and 31 respectively for MT19937.  Then we do a bunch of linear algebra to form a twist transformation (where the twister part of the name is derived) followed by a tempering transform to ensure as uniform of a distribution as possible. <\/p>\n<style type=\"text\/css\"><!--\n\/**\n * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n * (http:\/\/qbnz.com\/highlighter\/ and http:\/\/geshi.org\/)\n *\/\n.actionscript3  {font-size:80%; font-family:monospace;color: #006; border: 1px solid #d0d0d0; background-color: #f0f0f0;}\n.actionscript3 a:link {color: #000060;}\n.actionscript3 a:hover {background-color: #f0f000;}\n.actionscript3 .imp {font-weight: bold; color: red;}\n.actionscript3 .kw1 {color: #0033ff; font-weight: bold;}\n.actionscript3 .kw2 {color: #6699cc; font-weight: bold;}\n.actionscript3 .kw3 {color: #339966; font-weight: bold;}\n.actionscript3 .kw4 {color: #9900cc; font-weight: bold;}\n.actionscript3 .kw5 {color: #004993;}\n.actionscript3 .kw6 {color: #004993;}\n.actionscript3 .kw7 {color: #004993;}\n.actionscript3 .kw8 {color: #004993;}\n.actionscript3 .co1 {color: #009900; font-style: italic;}\n.actionscript3 .co2 {color: #009966; font-style: italic;}\n.actionscript3 .coMULTI {color: #3f5fbf;}\n.actionscript3 .br0 {color: #000000;}\n.actionscript3 .sy0 {color: #000066; font-weight: bold;}\n.actionscript3 .st0 {color: #990000;}\n.actionscript3 .nu0 {color: #000000; font-weight:bold;}\n.actionscript3 .me0 {color: #000000;}\n.actionscript3 span.xtra { display:block; }\n--!><\/style>\n\n\n\n\n\n<div class=\"actionscript3\"><span class=\"co1\">\/\/Mersenne Twister variables<\/span><br \/>\n<span class=\"kw1\">public<\/span> static <span class=\"kw2\">var<\/span> MT<span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=array%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:array.html\"><span class=\"kw5\">Array<\/span><\/a><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">public<\/span> static <span class=\"kw2\">var<\/span> indexMT<span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=int%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:int.html\"><span class=\"kw5\">int<\/span><\/a><span class=\"sy0\">;<\/span>\n\n\n<span class=\"co1\">\/\/---------------------------------------------------------------------------------------<\/span><br \/>\n<span class=\"co1\">\/\/***************************************************************************************<\/span>\n\n\n<span class=\"co1\">\/\/---------------------------------------------------------------<\/span><br \/>\n<span class=\"co1\">\/\/these functions compose the algorithm for a Mersenne Twister<\/span><br \/>\n<span class=\"co1\">\/\/see http:\/\/en.wikipedia.org\/wiki\/Mersenne_twister<\/span><br \/>\n<span class=\"co1\">\/\/This is a MT19937 implementation<\/span><br \/>\n<span class=\"co1\">\/\/named because it has a proven 2^19937 - 1 period (approx 4.3 * 10^6001)<\/span><br \/>\n<span class=\"co1\">\/\/(w, m, n, r) = (32, 624, 397, 31)<\/span><br \/>\n<span class=\"co1\">\/\/a = 0x9908B0DF<\/span><br \/>\n<span class=\"co1\">\/\/u = 11<\/span><br \/>\n<span class=\"co1\">\/\/(s, b) = (7, 0x9D2C5680)<\/span><br \/>\n<span class=\"co1\">\/\/(t, c) = (15, 0xEFC60000)<\/span><br \/>\n<span class=\"co1\">\/\/l = 18<\/span><br \/>\n<span class=\"co1\">\/\/it generates numbers in the range 0 to 2^32 - 1<\/span><br \/>\n<span class=\"co1\">\/\/----------------------------------------------------------------<\/span>\n\n\n<span class=\"co1\">\/\/while MT is the 'best' random number generator, it is considerably slower<\/span><br \/>\n<span class=\"co1\">\/\/then Flash's Math.random()<\/span>\n\n\n<span class=\"kw1\">public<\/span> static <span class=\"kw3\">function<\/span> initializeRandGenerator<span class=\"br0\">&#40;<\/span>seed<span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=uint%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:uint.html\"><span class=\"kw5\">uint<\/span><\/a><span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/the seed can be any positive integer<\/span><br \/>\n&nbsp; &nbsp; MT = <span class=\"kw1\">new<\/span> <a href=\"http:\/\/www.google.com\/search?q=array%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:array.html\"><span class=\"kw5\">Array<\/span><\/a><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; indexMT = <span class=\"nu0\">624<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; MT<span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span> = seed<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> i<span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=int%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:int.html\"><span class=\"kw5\">int<\/span><\/a><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span><span class=\"br0\">&#40;<\/span>i = <span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">624<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; MT<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span> = <a href=\"http:\/\/www.google.com\/search?q=uint%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:uint.html\"><span class=\"kw5\">uint<\/span><\/a><span class=\"br0\">&#40;<\/span>0xFFFFFFFF <span class=\"sy0\">&amp;<\/span> <span class=\"br0\">&#40;<\/span>0x6C078965 <span class=\"sy0\">*<\/span> <span class=\"br0\">&#40;<\/span>MT<span class=\"br0\">&#91;<\/span>i<span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span>MT<span class=\"br0\">&#91;<\/span>i<span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">30<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">+<\/span> i<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n<span class=\"br0\">&#125;<\/span>\n\n\n<span class=\"kw1\">public<\/span> static <span class=\"kw3\">function<\/span> quickRand<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=uint%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:uint.html\"><span class=\"kw5\">uint<\/span><\/a><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>indexMT == <span class=\"nu0\">624<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; indexMT = <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; generateRands<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> <span class=\"kw7\">y<\/span><span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=uint%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:uint.html\"><span class=\"kw5\">uint<\/span><\/a> = MT<span class=\"br0\">&#91;<\/span>indexMT<span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"kw7\">y<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">11<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"kw7\">y<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&lt;&lt;<\/span> <span class=\"nu0\">7<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&amp;<\/span> 0x9D2C5680<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"kw7\">y<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&lt;&lt;<\/span> <span class=\"nu0\">15<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&amp;<\/span> 0xEFC60000<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"kw7\">y<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">18<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; indexMT<span class=\"sy0\">++;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"kw7\">y<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span>\n\n\n<span class=\"kw1\">public<\/span> static <span class=\"kw3\">function<\/span> generateRands<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> i<span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=int%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:int.html\"><span class=\"kw5\">int<\/span><\/a><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> <span class=\"kw7\">y<\/span><span class=\"sy0\">:<\/span><a href=\"http:\/\/www.google.com\/search?q=uint%20inurl:http:\/\/livedocs.adobe.com\/flex\/201\/langref\/%20inurl:uint.html\"><span class=\"kw5\">uint<\/span><\/a><span class=\"sy0\">;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span><span class=\"br0\">&#40;<\/span>i = <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">227<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"br0\">&#40;<\/span>0x80000000 <span class=\"sy0\">&amp;<\/span> MT<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">+<\/span> <span class=\"br0\">&#40;<\/span>0x7FFFFFFF <span class=\"sy0\">&amp;<\/span> <span class=\"br0\">&#40;<\/span>MT<span class=\"br0\">&#91;<\/span>i<span class=\"sy0\">+<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; MT<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span> = MT<span class=\"br0\">&#91;<\/span>i <span class=\"sy0\">+<\/span> <span class=\"nu0\">397<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&amp;<\/span> 0x1<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> 0x9908B0DF<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/special case for i + 397 &gt; 624 to avoid a mod operator<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span><span class=\"br0\">&#40;<\/span>i = <span class=\"nu0\">227<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">623<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"br0\">&#40;<\/span>0x80000000 <span class=\"sy0\">&amp;<\/span> MT<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">+<\/span> <span class=\"br0\">&#40;<\/span>0x7FFFFFFF <span class=\"sy0\">&amp;<\/span> <span class=\"br0\">&#40;<\/span>MT<span class=\"br0\">&#91;<\/span>i<span class=\"sy0\">+<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; MT<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span> = MT<span class=\"br0\">&#91;<\/span>i <span class=\"sy0\">-<\/span> <span class=\"nu0\">227<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&amp;<\/span> 0x1<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> 0x9908B0DF<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/special case for last value, to avoid mod operator<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw7\">y<\/span> = <span class=\"br0\">&#40;<\/span>0x80000000 <span class=\"sy0\">&amp;<\/span> MT<span class=\"br0\">&#91;<\/span><span class=\"nu0\">623<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">+<\/span> <span class=\"br0\">&#40;<\/span>0x7FFFFFFF <span class=\"sy0\">&amp;<\/span> <span class=\"br0\">&#40;<\/span>MT<span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; MT<span class=\"br0\">&#91;<\/span><span class=\"nu0\">623<\/span><span class=\"br0\">&#93;<\/span> = MT<span class=\"br0\">&#91;<\/span><span class=\"nu0\">396<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&gt;&gt;&gt;<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">^<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">y<\/span> <span class=\"sy0\">&amp;<\/span> 0x1<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> 0x9908B0DF<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> &nbsp; <br \/>\n&nbsp; &nbsp; <br \/>\n<span class=\"br0\">&#125;<\/span>\n\n\n<span class=\"co1\">\/\/***************************************************************************************<\/span><br \/>\n<span class=\"co1\">\/\/---------------------------------------------------------------------------------------<\/span><br \/>\n&nbsp;<\/div>\n\n\n\n*Special thanks to the <a href=\"http:\/\/quickhighlighter.com\/\">Quick Highlighter<\/a> team for the code embed CSS and HTML\n\nSo the only real question left is what do you pick for a seed value?  If you always use the same number, the \u2018random generator\u2019 will always return the same sequence.  Therefore, you need a random way to seed the generator \u2013 quite the paradox.  You can use Flash\u2019s random number generator to provide an initialization integer, personally I think it\u2019s clever to derive a value from the date and time the application runs.\n\nThanks for reading, and remember, we are all in this together.\n\n\n\n<table cellspacing=\"15\">\n\n<tr>\n\n<td>\n<a class=\"DiggThisButton DiggMedium\"><\/a>\n<\/td>\n\n\n\n<td>\n<a href=\"http:\/\/reddit.com\/submit\" onclick=\"window.location = 'http:\/\/reddit.com\/submit?url=' + encodeURIComponent(window.location); return false\"> <img decoding=\"async\" src=\"http:\/\/reddit.com\/static\/spreddit7.gif\" alt=\"submit to reddit\" border=\"0\" \/> <\/a>\n<\/td>\n\n\n\n<td>\n\n\n\n<table>\n\n<tr>\n\n<td>\n<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/static.delicious.com\/img\/delicious.small.gif\" height=\"10\" width=\"10\" alt=\"Delicious\" \/>\n<\/td>\n\n\n\n<td>\n<a href=\"http:\/\/delicious.com\/save\" onclick=\"window.open('http:\/\/delicious.com\/save?v=5&noui&jump=close&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=550,height=550'); return false;\"> Bookmark this on Delicious<\/a>\n<\/tr>\n\n<\/table>\n\n\n<\/td>\n\n\n\n<td>\n<script src=\"http:\/\/www.stumbleupon.com\/hostedbadge.php?s=2\"><\/script>\n<\/tr>\n\n<\/table>\n\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Math.random() is the bane of many Flash game developers, and in this article I am going to help you work around it (free code).<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-181","post","type-post","status-publish","format-standard","hentry","category-actionscript-30"],"_links":{"self":[{"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/posts\/181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=181"}],"version-history":[{"count":36,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/posts\/181\/revisions"}],"predecessor-version":[{"id":587,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=\/wp\/v2\/posts\/181\/revisions\/587"}],"wp:attachment":[{"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stephencalenderblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}