Page 1 of 2
Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 8:39 am
by Helvecta
I'm checking out some of the features for 0.9 and the RNG doesn't want to play nice. Running the following (the wiki's example and an assertion to check the outcome) always returns "9". Since this is the wiki's example, I figure it should be more... random.
Code: Select all
function love.load()
rng = love.math.newRandomGenerator()
rng:setSeed(os.time())
randomNumber = rng:random(1,100)
assert(nil, randomNumber)
end
Can someone lay the knowledge smackdown on me? Thanks.
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 8:48 am
by slime
Does this give something more random?
Code: Select all
function love.load()
rng = love.math.newRandomGenerator()
rng:setSeed(os.time())
rng:random()
randomNumber = rng:random(1,100)
assert(nil, randomNumber)
end
Or maybe this:
Code: Select all
function love.load()
rng = love.math.newRandomGenerator()
rng:setSeed(tonumber(tostring(os.time()):reverse()))
randomNumber = rng:random(1,100)
assert(nil, randomNumber)
end
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 1:51 pm
by Helvecta
What on Earth..
Your first example runs like clockwork in reverse, decrementing by one every time I run it (I set the RNG to output a number between 1 and 10 and run the file roughly once a second); the second one only gives numbers between 1 and 6 when set up the same way, and seems to increment by one each time I run it. I suppose that's since the seed is based on os.time(), and I'm starting the application roughly once every second, but the random number shouldn't be incrementing by one just because os.time() is incrementing by one.. right!?
Output, first example:
Output, second example:
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 2:20 pm
by bartbes
Unfortunately the algorithm used (xorshift) produces very similar initial results for similar seeds, they should diverge, though.
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 2:37 pm
by Helvecta
Oh, alright; I suppose needing an RNG within the first couple seconds of an app's execution does seem unlikely, so I can live with that.
But what about this function?
Code: Select all
function Random(min, max, isFractional)
local gen = love.math.newRandomGenerator()
gen:setSeed(os.time())
local isFractional = isFractional or false
local randomNumber
if isFractional == true then
randomNumber = gen:random(min * 100, max * 100) / 100 -- math random doesn't play nice with decimals..
else
randomNumber = gen:random(min, max)
end
assert(nil, randomNumber) -- some debug junk
return randomNumber
end
the purpose of the function is to return a random number, but with support for decimals (maybe I'm wrong but playing with random suggests that it doesn't do decimals).
However, everytime I call the function,
the assertion returns -4.2, every time. Every time!
Something's funky here, but what? And why?
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 3:15 pm
by bartbes
Well, you're seeding too much, mostly.
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 4:08 pm
by Helvecta
I thought that :setSeed was necessary when setting up the RNG but
reading other stuff is agreeing with what you're advising. I guess by now you're figuring out that I'm not familiar with what makes an RNG less predictable.
Okay, so I need to reseed less, but I have nowhere else to set the seed since the RNG it's effecting is local and called in the function, so I'll just get rid of that line (removed: gen:setSeed(os.time())). Doing this has little effect; the RNG just spits out -0.26 at this point.
So looking back at Slime's post, I decide I should try to emulate it and generate a random number before I generate a random number (added: gen:random()), making the RNG spit out 3.35. Setting the seed again (added: gen:setSeed(os.time())) makes the number change each time, but it follows a predictable time-based pattern, running backwards from 5 to -5 (code below)
Code: Select all
function Random(min, max, isFractional)
local gen = love.math.newRandomGenerator()
gen:setSeed(os.time())
gen:random()
local isFractional = isFractional or false
local randomNumber
if isFractional == true then
randomNumber = gen:random(min * 100, max * 100) / 100 -- math random doesn't play nice with decimals..
else
randomNumber = gen:random(min, max)
end
assert(nil, randomNumber) -- some debug junk
return randomNumber
end
Why does it refuse to be random?
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 4:43 pm
by bartbes
So why does that RandomNumberGenerator need to be created there? You can create it elsewhere, or use the global one (love.math.random), that means you don't have to seed for every result.
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 4:44 pm
by Robin
A function that returns or uses a pseudo-random number
should not mess with the seed. You could do something like this:
Code: Select all
local gen = love.math.newRandomGenerator()
gen:setSeed(os.time())
gen:random()
function Random(min, max, isFractional)
local randomNumber
if isFractional then
randomNumber = gen:random(min * 100, max * 100) / 100 -- math random doesn't play nice with decimals..
else
randomNumber = gen:random(min, max)
end
assert(nil, randomNumber) -- some debug junk
return randomNumber
end
Re: Another Question About 0.9's RNG
Posted: Fri Dec 20, 2013 5:25 pm
by Helvecta
bartbes wrote:love.math.random
Oh, that's perfect, thanks for throwing that my way, I didn't know that existed.
That begs the question though: why does all this stuff about RandomGenerators even exist if the same can be done with love.math.random? Is it because of the control over the generator's seed? I guess so that you could replicate seemingly random numbers if you needed to?
Robin wrote:A function that returns or uses a pseudo-random number should not mess with the seed.
I'll keep that in mind, thanks! I tested out the example you posted in LOVE though and it still seems to generate a number "like clockwork". Maybe it's because of the way I'm testing it, but I don't think that should matter.
I recorded a video of it, too, to show you what I'm doing.
Figuring out what differentiates this from love.math.random - and figuring out how to actually make RandomGenerator work - would help me a ton, so any info clearing this up would be appreciated.