Math.Random question

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Luska72
Prole
Posts: 18
Joined: Thu Jan 03, 2013 6:14 pm

Math.Random question

Post by Luska72 »

I understand that math.random's seed in based on the os.clock. I am having a small problem with many random numbers declared many times in a row. Here is an example:

Code: Select all

for a=1, #objectsToMove do
local rand = math.random(-5,5)
objectsToMove[a].x = objectsToMove[a].x + rand * dt
end
This is an example of what I am talking about, in this instance all of the objects will move randomly, but in the same pattern. I want all the objects to move independently based on their own random number.

Any tips would be great, I'm pretty stumped!
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Math.Random question

Post by Inny »

It's your imagination.

Alright, the long answer is that math.random doesn't actually provide random numbers, it provides pseudorandom numbers. The distinction is that regular random numbers are generated from sources like you moving your mouse, or cosmic radiation, where as pseudorandom numbers start with a number, (like the current time) and keep adding and multiplying to them in some algorithm. HOWEVER, the "period" for PRNGs, or how many times it can generate a number before it loops back and starts over is immensely huge.

Anyway, a good tip, use math.random without any parameters. When you give it numbers, it returns integers. Without, it returns a real number between [0 and 1). That can increase the amount of diversity in their movement.

Another tip, you're moving them randomly every frame, which means you're going to get wiggling at best. Instead, pick a direction, speed, and time randomly, and try moving them in a straight line for that period before picking a new way to go.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Math.Random question

Post by Robin »

Yes, the real problem here is statistics: over a long period of time, on average all these enemies just keep bouncing back to the middle. Like Inny said: pick a direction/speed for them at the beginning and use that:

(Also, I use ipairs here instead of a numeric for.)

Code: Select all

-- in love.load
for i, obj in ipairs(objectsToMove) do
    obj.speed = math.random(-5,5)
end

-- in love.update
for i, obj in ipairs(objectsToMove) do
    obj.x = obj.x + obj.speed * dt
end
Help us help you: attach a .love.
Luska72
Prole
Posts: 18
Joined: Thu Jan 03, 2013 6:14 pm

Re: Math.Random question

Post by Luska72 »

Thank you very much for the replies, I still a little stumped though.

While I do (now) understand how random numbers are generated, I still don't know the best way to get different random numbers at the same os.time. How would I implement something like mouse movement or cosmic radiation to my random number?

Thank you very much again, Love2d has an awesome community!
Luska72
Prole
Posts: 18
Joined: Thu Jan 03, 2013 6:14 pm

Re: Math.Random question

Post by Luska72 »

In other words: How can I get a random number that is NOT based on os.time, because I generate multiple random numbers at the EXACT SAME TIME which causes them to all be the same.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Math.Random question

Post by Nixola »

Calling math.random even one thousand times in the same second still returns different numbers
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Math.Random question

Post by Robin »

If you're calling math.randomseed(), remove all those calls.

If not, could you upload your code (bundle it all together in a .love, please)?

Also, please don't double post.
Help us help you: attach a .love.
Luska72
Prole
Posts: 18
Joined: Thu Jan 03, 2013 6:14 pm

Re: Math.Random question

Post by Luska72 »

First of all, sorry about the double post. It will not happen again.

The computer I am on isn't working properly for making .love files (not admin on this comp). I will upload the .love file later when I get access to my home computer.

For now here is all the code I am using for the random:

rand.lua:

Code: Select all

rand = { }

function rand:init()
math.randomseed (os.time())
end

function rand:seed()
math.randomseed (os.time())
end

function rand:newInteger(low,high)
local randomNum
randomNum = math.random(low,high)
randomNum = math.random(low,high)
randomNum = math.random(low,high)
randomNum = math.random(low,high)
return randomNum
end

In love.load:

Code: Select all

rand:init()
In my npc.lua

Code: Select all

function npc:update(dt)
for i,v in ipairs(self.currentNPCs) do
	local direction = rand:newInteger(-5,5)
		v["x"] = v["x"] - direction * dt * 100
	end
end
end
I know the NPC code is bad right now, I plan on making NPCs move more smoothly after I get this random thing worked out.

Thank you again, I do appreciate you taking the time to help me out.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Math.Random question

Post by micha »

Ok, here is how random number generation on a computer works:

The code for generation random numbers has an internal state. Depending on that and on some complicated calculations, the next number is generated and then the state is updated. So next time you call the math.random function, you get a new random number.
These numbers are not truly random in the sense that in a certain state the algorithm will always generate the same random number. However the state is not visible to the user and the sequence that comes out of the generator looks random (unless you understand all the details of the algorithm, which I dont).

When you start your program, the state of the generator cannot be random, because the computer is deterministic. So if you set the state (seed) to a fixed number, then every time you start your program, you get the same sequence of random number. You don't want that. So in most implementations the random seed is set according to the system time. This has only to be done once. After that the sequence you get is as random as it can.

Now in löve, the setting of the random seed is done anyway at start up (guys correct me, when I'm wrong here). So you don't even need to ever call the randomseed function yourself. Never.

The only application I see, where you need to set the randomseed, is when you do scientific applications and want reproducible results. In that case you can set the seed to a number you know and get the same random sequence every time.

Edit: Also, if you need one random number, there is no point in calling the math.random function multiple times. There is no visible correlation between to consecutive function calls.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Math.Random question

Post by Roland_Yonaba »

micha wrote: When you start your program, the state of the generator cannot be random, because the computer is deterministic. So if you set the state (seed) to a fixed number, then every time you start your program, you get the same sequence of random number. You don't want that. So in most implementations the random seed is set according to the system time. This has only to be done once. After that the sequence you get is as random as it can.
Totally. Actually, you use math.randomseed for that.
Pil covers the topic, take a quick peek here. Lua-users have a dedicated topic about that, aswell.
micha wrote: Now in löve, the setting of the random seed is done anyway at start up (guys correct me, when I'm wrong here). So you don't even need to ever call the randomseed function yourself. Never.
You're quite right, Micha. Well, it seems that this was introduced in love 0.8.0. See love.run default implementation.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 247 guests