Portable Seedable Random Number Generator

No replies
OderWat
User offline. Last seen 28 weeks 1 day ago. Offline
Joined: 4 Jun 2010

I am pretty new with Lua and with Corona SDK. But as I am enjoying all your example Code offered here I want to pay some back for you to use which was made by me:

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
require('crypto')
 
local digest=crypto.digest
local md5=crypto.md5
 
GameRand = {
        my_step=1,
        my_seed=false,
        digest='',
        pos=1
}
 
function GameRand:new(o)
        o = o or {}
        setmetatable(o, self)
        self.__index = self
        return o
end
 
function GameRand:seed(s)
        self.my_seed=s
        self.my_step=0
        self.pos=1
        self.digest=digest(md5,self.my_seed,true)
end
 
function GameRand:step(step)
        local i
        for i=1, step do
                self:rand09()
        end
end
 
function GameRand:rand09()
        if self.pos>16 then
                self.digest=digest(md5,self.digest,true)
                self.pos=1
        end
 
        local x=math.floor(string.byte(string.sub(self.digest,self.pos,self.pos))*10/256)
        self.pos=self.pos+1
        self.my_step=self.my_step+1
        return x
end

Example of Usage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- GameRand basic test
 
gr=GameRand:new()
 
print('Show 20 Random Values')
gr:seed('test')
for x=1, 20 do
        print(x..': '..gr:rand09())
end
 
print('\nRestart at Step 18')
gr:seed('test')
gr:step(17)
for x=18, 20 do
        print(x..': '..gr:rand09())
end

Similiar Code is used in my upcoming first Corona Game to create the same random number sequence for the same seed.

The speciality is, that this code is portable between all hardware and languages I used while prototyping the game: PHP / Python / Objective-C and LUA on Windows, Linux and Mac OSX.

It is based on a simple usage of MD5 hashes for random number generation and pretty fast because MD5 is available as "native" implementation for all the script languages I used.

In addition the code has a (very simple) function to restore the state by a simple "bruteforce" approach knowing the original (public) seed and the current step.

To save the state you can simply serialize and unserialize the object anyway.

The distribution of random numbers is good enough for my gaming needs. If you need to make your chain of numbers unpredictable you can add some "magic" string to your seed.

As I am new to Lua I appreciate all hints about how to make the code better of faster :)