An Improved Random Number Generator
Saturday, 17th August 2019
I don't know where I went wrong, but my attempt to adapt the random number generator I found ended up as complete nonsense. Once my expression was simplified, I ended up dividing and multiplying by the same number, so that only rounding or overflow errors would produce a number different from the last. So I scrapped the subroutine I'd written and went for a simple approach that I can understand.
The idea of most pseudorandom number generators is to apply a series of arbitrary arithmetic or bitwise operations that produce a result whose pattern is difficult to discern. The better ones will go further to avoid detectable patterns. I don't have the mathematical knowledge to foresee when detectable patterns might occur, so I used trial and error. For the silly little games I want to write in Tiny BASIC, my generator doesn't have to be good, it simply has to be good enough.
In the end, I found that at least for numbers 1 to 10, just these steps were required: (1) multiply the current seed by 13, ignoring overflow errors; (2) subtract that from 32767; (3) keep that as the seed, but divide it by 2 for the return value. Steps (1) and (2) alone give a succession of numbers all of which are odd or all of which are even, and step (3) disguises that.
Below is the resulting random number subroutine. S will have to be set or input at the start of the program.
REM --- Random number generator REM Input: S - current seed REM Outputs: S - updated seed REM R - generated random number 200 LET S=32767-S*13 LET R=S/2 IF R<0 THEN LET R=-R RETURN