math.random bug?

35 replies [Last post]
wsterdan
User offline. Last seen 2 weeks 5 days ago. Offline
Joined: 25 Dec 2009

Hi;

Just starting to delve into Corona and Lua, and I'm having a minor problem with the simple math.random function. I have a ship that's supposed to start each new screen at a random position and rotation, and while it works perfectly in the simulator, on my first-gen iPod Touch it always appears in the same position with the same rotation. Is this a bug, or do I need to generate a random seed for each new screen?

The math.random code is pretty simple:

1
2
3
     FedShip.x = math.random(32, 250)
     FedShip.y = math.random(32, 450)
     FedShip:rotate(45 * (math.random (0, 7)))

Any suggestions would be appreciated.

-- Walt Sterdan

Replies

Rozek
User offline. Last seen 1 year 3 weeks ago. Offline
Joined: 25 Dec 2009

Walt,

have you tried to use "math.randomseed(x)" in order to set the seed of the built-in pseudo-random generator? You may use the current date/time in order to get a "random" "x".

Kind rgeards,

Andreas Rozek

wsterdan
User offline. Last seen 2 weeks 5 days ago. Offline
Joined: 25 Dec 2009

Hi Andreas;

No, I haven't tried it yet; I was curious if I had to, or if there was a bug in the math.random function that might be fixed in the next update.

I will give it a try rather than waiting, though, thanks.

-- Walt Sterdan

Jeff Johnson's picture
Jeff Johnson
User offline. Last seen 1 year 28 weeks ago. Offline
Joined: 3 Jun 2009

math.random will result in a "random" number every time you do a command-R in the simulator, but if you actually relaunch the simulator, the number will always be the same. This has to do with the seed on the system being the same. Doing something like math.randomseed(os.time()) or randomseed(os.clock()) will yield a more random number.

wsterdan
User offline. Last seen 2 weeks 5 days ago. Offline
Joined: 25 Dec 2009

Thanks for the clarification, it's appreciated.

Just wanted to add that I'm really enjoying Corona, great job!

--Walt Sterdan

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

I am having the same problem with my random not being random. What is wrong with my code?

1
2
math.randomseed(os.clock());
canToPop=math.random(numOfCans);

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

use os.time() instead of os.clock()

math.randomseed( os.time() )

carlos

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

Same problem..

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

what is value for numOfCans?

Here is the semantics for math.random

math.random(fooValue) generates integer numbers between 1 and upper. (numOfCans?)
math.random(foolowerValue, fooupperValue) generates integer numbers between lower and upper.

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

numOfCans is a tonumber(event.id) from a button press. tpye(numOfCans) is number when tested.

The result is supposed to be a number between 1 and numOfCans.

The result is in the correct range, its just always the same pattern of numbers. It seems the randomseed is not working.

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

send me some code...

info@anscamobile.com

c

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

Email Sent.

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

Got it, replied.

math.randomseed( os.time() ) -- needed to be placed at the top of the file.

The issue was randomseed was called everytime right before math.random was being called, thus not seeding the right random number.

c

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

Hmm.. this bug is back.. Fixed another piece of code that was masking this problem (buttons were being called multiple times on single button presses)

Can I send you the code again?

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

yes, please send code to info@anscamobile.com, or suppor@anscamobile.com

carlos

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

Still waiting for a response...

evank
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 16 Sep 2009

This may sound crazy, but what happens if you call a few random numbers (and, say, print them to the terminal). Is the SEQUENCE the same each time?

I ask because I think I've hit cases where the first "random" number tended to come out the same each time, even with a random seed, but then later numbers in the series would have more random-looking values. So I just discarded the first number and used the second one.

However, if you're getting entire identical sequences, then something else is wrong.

s.w.powers
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 16 Mar 2010

Since I've seen a few examples (not here, but in other places) where folks set the random seed multiple times, I wanted to point out you only want to set it *once*. Setting it more than once just screws with the algorithm. Typically, one would set the seed with a call to "time(0)" as that is, on most systems, the number of seconds since the "epoch" (when unix first came to life). Now, I could be wrong, but this is, in my experience, still a very standard library call and in lua it's available with "os.time()". It does depend on the hardware you're on, but the iPhone definitely supports this convention and I would suggest that any platform we would be using Corona on will as well. Using os.clock() is not a reliable thing since it's very conceivable you'll get the same number (or very close to the same number) each time you run your app since it's the number of CPU seconds used since starting your app... whereas "os.time()" will always (unless called again within the same second) be different. And since you only seed *once*, this should never be an issue.

The "pseudo-random" algorithm, simply put, generates a pseudo-random sequence of numbers. Calling random just grabs the next one in the sequence. Setting seed more than once will just reset the sequence and actually give you less randomness.

What a lot of folks also don't know (and why the OP considered the behavior to be a bug) is the same seed will generate the *same* sequence of numbers! This is a very good thing! :) Say you randomly generate a dungeon or a set of obstacles in your game. Well, you can now "save" that level simply by storing your random seed you used to generate it... instead of saving the entire level data. To recreate it, just set your seed and run through the same algorithm. Of course, this will only work if you don't change how you generate your level, but for certain things it's quite nice.

At any rate, set the seed once, then call random multiple times.

In the latter part of this thread the indication was it generated the same result. This is most likely exactly what evank was saying: You're likely just encountering the same starting numbers. If you are taking random(1,5) you have a very small sample set and will end up with similar sequences (or at least the feel of similar sequences) no matter what was being used to generate "random" numbers since you literally only have 5 numbers to choose from.

Hope this helps a little bit in understanding how random works.

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

I am well aware of how random numbers and seeds work. There was a bug in my code that was changing the seed each time, but that still should not have given me the same "random" number every time in the original version I had thrown together for testing. Even when the random seed was put in the right spot (out of the loop), the first random number was always the same, and as my game loop never needed a second random, I never got anything but the first number, which was always the same. After discussing with the developers, it seems that a simple discard of the first random number will allow the following randoms to be correct.

I still consider this a bug, but one I can work around.

(I am not some beginner programmer, I am just new to Corona and LUA. I have my BS and MS in Computer Science and work as a developer for business applications)

s.w.powers
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 16 Mar 2010

No need to get defensive, more than just you read these bug reports and there was enough conjecture here (as well as in other places) that I wanted to post about not seeding multiple times... just to be sure. I don't know you, I couldn't tell your level of expertise.

I, also, recently ran into the random bug you point out (it is indeed a bug) and it was very simple to reproduce.

So, devs, here you go: main.lua ::

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
-- without seeding, you get a different sequence and different starting number every run
print("No Seed Set");
for i = 1, 10 do
  print(math.random(1, 100));
end;
<code>
-- as soon as you seed, you get the same starting number
_seed = os.time();
print("Seed: ".._seed);
math.randomseed(_seed);
for i = 1, 10 do
  print(math.random(1, 100));
end;
<code>
-- and again to demonstrate the same problem each re-seed
_seed = _seed + 1;
print("Seed: ".._seed);
math.randomseed(_seed);
for i = 1, 10 do
  print(math.random(1, 100));
end;
<code>
-- finally, the workaround
_seed = _seed + 1;
print("Seed: ".._seed);
math.randomseed(_seed);
math.random(); -- <<<<< this is the work around...ick.
for i = 1, 10 do
  print(math.random(1, 100));
end;

If you seed, this shows the first number in each sequence to be the same.
Specifically, if you re-seed you again get the same number for the first in the sequence.
And the last run shows the workaround.

I did some further testing and found some odd things:

1) Over a period of about 10 minutes, the first number went from 25 to 26 to 27. I was not able to reproduce what this coincided with.
2) It appears to only be related to actually calling math.randomseed and then running through a sequence. When I do not seed, I get a different sequence (and first number) ever time I run the test. So it appears this bug is directly in connection with performing a seed.

I completely agree with menace960 -- while there is a workaround, this is definitely a bug and one that comes up each time you seed. This should definitely be flagged as a priority bug since anyone using randomseed will get bitten.

Scott

carlos m. icaza's picture
carlos m. icaza
User offline. Last seen 7 hours 25 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

Added into our bug base to look into and fix

thanks

Carlos

seanh
User offline. Last seen 7 hours 45 min ago. Offline
Ansca Staff
Joined: 3 Jun 2009

(Logged as bug #134)

MBD's picture
MBD
User offline. Last seen 4 hours 21 min ago. Offline
Joined: 14 Sep 2010

I'm not able to get math.random to work on the iphone4 side. My random word generator works on the Android side, and in the emulator but opening up the dev app on the iphone 4 shows the exact same results every time.
I've tried the math.randomseed(os.clock()); before attemting any randomization but it doesn't help.

Is there a new bug?

MBD's picture
MBD
User offline. Last seen 4 hours 21 min ago. Offline
Joined: 14 Sep 2010

I just did some further testing and I can almost confirm this is a bug on compile. I took an app that we have published in the apple app store and recompiled it using the new version of Corona. On the iphone4 - math.random is no longer working as it did when I compiled the published app early December 2010.

Arg, very frustrating as I was almost finished with a new app when I spotted this bug.

Help -

IgnacioIturra
User offline. Last seen 11 weeks 5 days ago. Offline
Joined: 31 Oct 2010

If you had even bothered to look through the thread you would know you need to use os.time() instead of os.clock() for your seed.

MBD's picture
MBD
User offline. Last seen 4 hours 21 min ago. Offline
Joined: 14 Sep 2010

@IgnacioIturra - Of course I looked through the thread, I try to practice studying a problem well enough before posting blindly into the forum and filling everyones inbox with nonsense..
I tried all methods I could find to get the function to work but it's still not working on the iphone side.
Did you try and duplicate the problem for yourself by compiling for iphone4 or are you just posting blindly without "bothering" to do the work ;)? Sorry -couldn't resist!
I just want the bug fixed -

menace690
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 10 Mar 2010

I stopped using Corona after my initial trial expired due to this bug. Just an FYI

IgnacioIturra
User offline. Last seen 11 weeks 5 days ago. Offline
Joined: 31 Oct 2010

"I've tried the math.randomseed(os.clock()); before attemting any randomization but it doesn't help."

That alone tells me you haven't. As a matter of fact I HAVE dealt with this bug during development of my game and it was fixed by following the instructions in this very thread (which you haven't properly read if you still can't fix it).

I'll reiterate just for your benefit.

math.randomseed(os.time())

at the beginning of your code. Just once (make sure it's not in a loop or called again).
then

math.random()

Once. That number will always be the same. As long as you discard it, you can use math.random again and the rest of the numbers will be "random".

If you don't do this, it'll work fine on the simulator (which is why I had so much trouble finding the bug), but won't work right on your iphone.

MikeHart
User offline. Last seen 1 week 2 days ago. Offline
Joined: 22 Mar 2010

>>Once. That number will always be the same.

And it is not a problem of Corona but with Lua. We have discussed this extensively here last year.

rdcube's picture
rdcube
User offline. Last seen 1 week 1 day ago. Offline
Joined: 26 Jul 2010

ignacio and/or mike, could you please post sample code on how you propose we approach this workaround? It could benefit the rest of us newbies ;)

Thanks,
RD

IgnacioIturra
User offline. Last seen 11 weeks 5 days ago. Offline
Joined: 31 Oct 2010

But, but, but.., I just did that.

It's really no more complicated than having this at the start of your main.lua

1
2
math.randomseed(os.time())
math.random()

Then just use math.random() normally and it'll work fine.

s.w.powers
User offline. Last seen 1 year 4 weeks ago. Offline
Joined: 16 Mar 2010

Post #17 from this thread gives a decent run down on how to actually seed and use random correctly:
http://developer.anscamobile.com/forum/2010/01/05/mathrandom-bug#comment-1417

Post #19 gives example code which will show the problem and the last snippet shows the work around. This is also specified in the comment right before yours.
http://developer.anscamobile.com/forum/2010/01/05/mathrandom-bug#comment-1439

For clarification:

1
2
3
4
5
6
7
8
9
_seed = os.time();
-- finally, the workaround
-- _seed = _seed + 1; commented out as it is not germane to this snippet
print("Seed: ".._seed);
math.randomseed(_seed);
math.random(); -- <<<<< this is the work around...ick.
for i = 1, 10 do
  print(math.random(1, 100));
end;

As others have pointed out, all right from here in this very thread. :)

All you need to do is seed once with os.time() and then call random once and ignore it's value. From that point on the correct random number sequence is generated.

Scott

rdcube's picture
rdcube
User offline. Last seen 1 week 1 day ago. Offline
Joined: 26 Jul 2010

Yeah, I saw (glimpse) at the posts you mentioned, but it didn't clicked.
Sometimes devs don't realize that new blood is coming to the forums and are learning (even experience ones).

New devs are also looking for 'friendly forums'; some are afraid of asking question for fear of sounding "dumb" and leave.
Take a look at what menace690 posted, he left because he thought it was bug that was never going to be fixed.

Keep in mind that if potential corona users don't buy the software because they don't feel "right", that's money that Ansca is losing; and if Ansca doesn't make money, corona could well be extinct (I'm exaggerating, but it has happened )

All this long thread could've been avoided (perhaps at post #17) if something as simple as the (but, but, but) was posted earlier.

Sorry for the rumble.

Thanks and cheers ;)

RD

walter
User offline. Last seen 2 hours 41 min ago. Offline
Ansca Staff
Joined: 22 Jun 2009

Yes, this problem has has been around for years. Anyone who's relied on the rand() function in libc (which is what Lua relies on) has seen this problem. Here's a note from one of the creators of Lua documenting the issue almost 4 years ago:

http://lua-users.org/lists/lua-l/2007-03/msg00564.html

mrgoose
User offline. Last seen 30 min 38 sec ago. Offline
Joined: 24 Jun 2009

According to this post:
http://lua-users.org/wiki/MathLibraryTutorial

... OSX and FreeBSD have issues.

The solution proposed was based on the idea that os.time() returns a relatively similar number each time. For example, here are two os.time() values separated by roughly one day (A day has 86400 seconds)

1
2
1327302026 -- today
1327388297 -- some time tomorrow

As you can see, the numbers are strikingly close, all things considered.

The post above explains some garbal about "high bits" and "low bits', so my instinct leads me to believe that what they are trying to say is that the seed number itself needs to be a bit more sporadic... or random, if you will.

Hence, they propose the following solution:

1
2
3
4
5
math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )
-- or for a larger sample, drop the "sub":
-- math.randomseed( tonumber(tostring(os.time()):reverse()) )
-- or to get an even larger timestamp with milliseconds:
-- math.randomseed( tonumber(tostring(os.time() + math.round( system.getTimer()):reverse()) )

... which essentially reverses the os.time() so that the last number is first, thereby feeding seed numbers that are vastly different:

1
2
6202037231 -- today
7928837231 -- some time tomorrow

nick_sherman's picture
nick_sherman
User offline. Last seen 7 hours 26 min ago. Offline
Joined: 23 Sep 2011

Thanks for that, I too have seen that random numbers aren't quite as random as I'd like.

As an aside, I've been using this library for my games which require procedural generation - it will give the same set of random numbers for a given seed across all platforms.

http://developer.anscamobile.com/code/portable-seedable-random-number-generator

Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.