1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
" Rndm:
" Author: Charles E. Campbell, Jr.
" Date: May 28, 2004
" Version: 3
"
" Discussion: algorithm developed at MIT
"
" <Rndm.vim> 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
" ---------------------------------------------------------------------
|