" Rndm: " Author: Charles E. Campbell, Jr. " Date: May 28, 2004 " Version: 3 " " Discussion: algorithm developed at MIT " " uses three pseudo-random seed variables " g:rndm_m1 g:rndm_m2 g:rndm_m3 " Each should be on the interval 0 - 100,000,000 " " RndmInit(s1,s2,s3): takes three arguments to set the three seeds (optional) " Rndm() : generates a pseudo-random variate on [0,100000000) " Urndm(a,b) : generates a uniformly distributed pseudo-random variate " on the interval [a,b] " Dice(qty,sides) : emulates a variate from sum of "qty" user-specified " dice, each of which can take on values [1,sides] " --------------------------------------------------------------------- " Randomization Variables: " with a little extra randomized start from localtime() let g:rndm_m1 = 32007779 + (localtime()%100 - 50) let g:rndm_m2 = 23717810 + (localtime()/86400)%100 let g:rndm_m3 = 52636370 + (localtime()/3600)%100 " --------------------------------------------------------------------- " RndmInit: allow user to initialize pseudo-random number generator seeds fun! RndmInit(lm1,lm2,lm3) let g:rndm_m1 = a:lm1 let g:rndm_m2 = a:lm2 let g:rndm_m3 = a:lm3 endfun " --------------------------------------------------------------------- " Rndm: generate pseudo-random variate on [0,100000000) fun! Rndm() let m4= g:rndm_m1 + g:rndm_m2 + g:rndm_m3 if( g:rndm_m2 < 50000000 ) let m4= m4 + 1357 endif if( m4 >= 100000000 ) let m4= m4 - 100000000 endif if( m4 >= 100000000 ) let m4= m4 - 100000000 endif let g:rndm_m1 = g:rndm_m2 let g:rndm_m2 = g:rndm_m3 let g:rndm_m3 = m4 return g:rndm_m3 endfun " --------------------------------------------------------------------- " Urndm: generate uniformly-distributed pseudo-random variate on [a,b] fun! Urndm(a,b) " sanity checks if a:b < a:a return 0 endif if a:b == a:a return a:a endif " Using modulus: rnd%(b-a+1) + a loses high-bit information " and makes for a poor random variate. Following code uses " rejection technique to adjust maximum interval range to " a multiple of (b-a+1) let amb = a:b - a:a + 1 let maxintrvl = 100000000 - ( 100000000 % amb) let isz = maxintrvl / amb let rnd= Rndm() while rnd > maxintrvl let rnd= Rndm() endw return a:a + rnd/isz endfun " --------------------------------------------------------------------- " Dice: assumes one is rolling a qty of dice with "sides" sides. " Example - to roll 5 four-sided dice, call Dice(5,4) fun! Dice(qty,sides) let roll= 0 let sum= 0 while roll < a:qty let sum = sum + Urndm(1,a:sides) let roll= roll + 1 endw return sum endfun " ---------------------------------------------------------------------