Code is not running in the device as it does in the simulator

I have a function that randomly selects a picture from a table and display it. In the simulator the sample code below works perfectly, when I send it to device, only the first element from the table is selected. Any ideas? I can share the full app code if someone is interested in to take a look.

local temp = {“alex”,“john”,“josh”}
local tempNum = #temp

local function selectRandom(tName)
if (tName==“Random” or tName=="" or tName==nil) then
local randTemp = math.random(tempNum)
tempName = temp[randTemp]
local img=display.newImage(tempName…".jpg")
end

end

selectRandom() [import]uid: 4883 topic_id: 924 reply_id: 300924[/import]

do you seed the random number generator somewhere at first? [import]uid: 5712 topic_id: 924 reply_id: 2185[/import]

I do this at the beginning of my app

math.randomseed(os.time())
dummy = math.random(0,255)
this takes care that the random numbers are always different. [import]uid: 5712 topic_id: 924 reply_id: 2186[/import]

why do I have to use math.randomseed? considering my other languages experience, all I should do was to use the random function… I will try. thanks! [import]uid: 4883 topic_id: 924 reply_id: 2187[/import]

generally a random number generator take a certain time value into account. With Lua/Corona it is when an app starts the apps runtime. So you will usually get always the same numbers. I think I seen this behaviour with other programming languages too. [import]uid: 5712 topic_id: 924 reply_id: 2190[/import]

The simulator is working great with the seed (every time i run it it comes with another data) but, when I move it to the device, the same image appears all the time.

Any ideas on what I could do here? [import]uid: 4883 topic_id: 924 reply_id: 2463[/import]

Not without seeing the code for a working example of the problem. [import]uid: 5659 topic_id: 924 reply_id: 2466[/import]

Did you seed the random generator at the start of your app like I showed you? Plus that dummy call of math.random? [import]uid: 5712 topic_id: 924 reply_id: 2468[/import]

Here goes:

math.randomseed = ( os.time() )
local tNum = 150
local places = {“place1”, “place2”, “placeN”}

– Select a place randomically
local function selectRandom(tName)
if (tName==“Random” or tName=="" or tName==nil) then
–pick a random place, otherwise get the tName informed
randT = math.random(tNum)
randT = math.random(tNum)
tFile = places[randT]
else
tFile = tName
end

end
–Pick a temple to display
local randT = 0
randT = math.random(tNum)
selectRandom() [import]uid: 4883 topic_id: 924 reply_id: 2469[/import]

So no dummy call. There is a topic here on the forum, that the the first math.random call is always the same. That is why I posted about the dummy call. [import]uid: 5712 topic_id: 924 reply_id: 2471[/import]

I just verified that the dummy call IS needed or your random number always starts out the same. I tested this in the Corona SDK 1.1 simulator.

I went to the Lua.org demo site, http://www.lua.org/cgi-bin/demo, and entered the same code and it worked without the dummy call. I thought the Corona build was based on Lua 5.1 so I’m not sure why the Corona build fails to work correctly.

Tom [import]uid: 6119 topic_id: 924 reply_id: 2479[/import]

Here is the code. With the second line commented out, it shows the same number every time in the Simulator/terminal (99).

math.randomseed(os.time())  
--dummy = math.random(0,255)  
a = math.random(150)  
print(a)  

Tom [import]uid: 6119 topic_id: 924 reply_id: 2480[/import]

Seen while digging the random “problem” on mac osx:

"Lua's random uses C's rand and srand functions.
The C90 standard defines the precise implementation of rand and srand,
and this algorithm isn't the best.
It especially lacks randomness in the lower bits.

Some platforms like Linux changed the implementation of rand to an
intentionally non-conforming, and better, implementation (e.g. random(3)).
OS/X remains true to the standard rand implementation, and Lua inherits it."

I ran into the “problem” too. The simulator on lua.org executes the code you type on a linux machine, hence bypassing our osx platform behavior.

"Lua on mac osx converts the integer returned by rand() into
a real number, effectively preserving only the high bits in the result.
When you call math.random(1,100) from Lua on mac osx,
the low-bit difference vanishes and you see the same integer result."

Here is what I am using to bypass the “same number always” oddity (works ok but not the best):

local \_seed = os.time()  
local function getRandom(f,c)  
 \_seed = \_seed + 1  
 math.randomseed(\_seed)  
 math.random()  
 local a = math.random(f,c)  
 \_seed = \_seed + a  
 return (a)   
end  
--get a random integer between 1 and 10  
print (getRandom(1,10))  

Maybe Ansca would work on that ? Quite annoying, indeed :slight_smile: [import]uid: 6050 topic_id: 924 reply_id: 2481[/import]

Hasufel,

There is absolutely no need to re-seed like that. It actually makes your random numbers *less* random. I posted about this in a different thread when we were discussing the original issue a while back, but here’s the short version:

  1. Rand is an algorithm. It generates pseudo random numbers based on the seed given it.
  2. Each time you feed it a different seed, you restart the random algorithm itself, in effect, you are taking the first number in a random sequence each time you call your “getRandom” function. This is not how the algorithm is intended to work and by doing it this way you actually make things less random.
  3. The workaround is exactly as Mike posted. You seed once at the start of your app (with os.time()), then you immediately follow that with a dummy call to math.random(). From that point forward, you will get the correct random numbers.

The only time you should want to “re-seed” is if you are wanting to run the same sequence. This is often desirable to reproduce the same path previously. For instance, if you had a game where the setup was based on random numbers (like a sudoko or something), if you save the seed you use to create the board, then you can regenerate that board again just by setting the seed to the same number. The only gotcha is if you change any of the code so you don’t utilize the random numbers in the same way.

At any rate, the point is, don’t re-seed, that’s a bad practice and totally unnecessary. Seed once, make a dummy math.random call, and you’re good to go.

Scott [import]uid: 5659 topic_id: 924 reply_id: 2483[/import]

Thanks Scott for helping out.
I knew my trick was awful: I found it odd.
It works like a charm as Mike posted.
My bad !
Thank you :slight_smile: [import]uid: 6050 topic_id: 924 reply_id: 2488[/import]

No problem. This oddity about math.random should be mentioned inside the App Programming Guide in big bold letters :slight_smile: [import]uid: 5712 topic_id: 924 reply_id: 2491[/import]

My friends, fact is, no matter I call the dummy or not (and I am calling), first number in the device is always the same. do you have any tested code showing how to get a new number in the device?
thanks! [import]uid: 4883 topic_id: 924 reply_id: 2495[/import]

math.randomseed(os.time());  
math.random();  
  
for i = 1, 10 do  
 print(i..") "..math.random());  
end  

Every time I reload I get different numbers for all 10.

Simple tests like this put at the top of your main.lua can easily show you if you are making a mistake in your code or if it’s an issue with lua.

Scott [import]uid: 5659 topic_id: 924 reply_id: 2497[/import]

Just tried your code. When you replace your code limiting the numbers in the random function, you will always get 1 as first number:

math.randomseed(os.time());
math.random(10); --considering the final table will have 10 elements

for i = 1, 10 do
print(i…") "…math.random(i));
end [import]uid: 4883 topic_id: 924 reply_id: 2500[/import]

Trying not to smile too much. :slight_smile:

That’s not how random works.

From lua.org Reference document:

math.random ([m [, n]])

This function is an interface to the simple pseudo-random generator function rand provided by ANSI C. (No guarantees can be given for its statistical properties.)

When called without arguments, returns a uniform pseudo-random real number in the range [0,1). When called with an integer number m, math.random returns a uniform pseudo-random integer in the range [1, m]. When called with two integer numbers m and n, math.random returns a uniform pseudo-random integer in the range [m, n].

First off, the dummy call is a dummy call. No need to pass anything to it.

Second, here’s the loop you ran through:

Loop 1: Give me a random number between 1 and 1.
Loop 2: Give me a random number between 1 and 2.
Loop 3: Give me a random number between 1 and 3.
Loop 4: Give me a random number between 1 and 4.
Loop 5: Give me a random number between 1 and 5.
Loop 6: Give me a random number between 1 and 6.
Loop 7: Give me a random number between 1 and 7.
Loop 8: Give me a random number between 1 and 8.
Loop 9: Give me a random number between 1 and 9.
Loop 10: Give me a random number between 1 and 10.

Take the “i” out of the math.random call and replace it with the range you want. It sounds like you want a number between 1 and 10, so that would be math.random(10).

Scott [import]uid: 5659 topic_id: 924 reply_id: 2501[/import]