Module:Random
From IdleOn MMO Wiki
Documentation for this module may be created at Module:Random/doc
require('strict')
local Assert = require('Module:Assert')
local bit32 = require('bit32')
--- @class Random
--- @field seed number
--- @field seed2 number
local Random = {}
local function imul(a, b)
return bit32.bor(a * bit32.band(b, 65535) + bit32.bor(bit32.lshift((a * (bit32.rshift(b, 16))), 16), 0), 0)
end
local function hash(a, b)
if b == nil then
b = 5381
end
a = imul(a, -862048943)
a = imul(bit32.bor(bit32.lshift(a, 15), bit32.rshift(a, 17)), 461845907)
b = bit32.bxor(b, a)
b = bit32.bor(imul(bit32.bor(bit32.lshift(b, 13), bit32.rshift(b, 19)), 5) + -430675100, 0)
b = imul(bit32.bxor(b, bit32.arshift(b, 16)), -2048144789)
b = imul(bit32.bxor(b, bit32.arshift(b, 13)), -1028477387)
return bit32.bxor(b, bit32.arshift(b, 16))
end
function Random:_nextSeeds()
self.seed = 36969 * bit32.band(self.seed, 65535) + bit32.arshift(self.seed, 16)
self.seed2 = 18e3 * bit32.band(self.seed2, 65535) + bit32.arshift(self.seed2, 16)
end
function Random:new(a)
Assert.isType(a, { 'nil', 'number' }, 'Seed must be either nil or a number')
local seed = a
if seed == nil or seed == 0 then
seed = 1
end
local seed2 = hash(a)
if seed2 == 0 then
seed2 = 1
end
return setmetatable({
seed = seed,
seed2 = seed2
}, { __index = Random })
end
function Random:random(a)
self:_nextSeeds()
return bit32.band(bit32.bor(bit32.lshift(self.seed, 16) + self.seed2, 0), 1073741823) % a
end
function Random:rand()
return self:random(10007) / 10007
end
function Random:srand(a)
if a == nil then
a = 1
end
self:_nextSeeds()
return bit32.bor(bit32.lshift(self.seed, 16) + self.seed2, 0) % 10007 / 10007 * a
end
function Random:int()
self:_nextSeeds()
return bit32.bor(bit32.lshift(self.seed, 16) + self.seed2, 0)
end
function Random:uint()
self:_nextSeeds()
return bit32.band(bit32.bor((bit32.lshift(self.seed, 16) + self.seed2), 0), 1073741823)
end
return Random