Shuffling table values

I have a problem with the following shuffle function. I’m trying to shuffle table (animalNames) values with a function (shuffle). It works in the simulator but not on a device. Any help is appreciated!

( I need this to be able to create display objects with random images. Maybe there is some other way to do this? )

[code]
animalNames = {}
table.insert (animalNames,“animal-duck-l.png”)
table.insert (animalNames,“animal-frog-l.png”)
table.insert (animalNames,“animal-giraffe-l.png”)
table.insert (animalNames,“animal-hippo-l.png”)
table.insert (animalNames,“animal-monkey-l.png”)
table.insert (animalNames,“animal-octopus-l.png”)
– function that shuffles the table values
function shuffle( a )
local c = #a
for i = 1, c do
local ndx0 = math.random( 1, c )
a[ndx0], a[i] = a[i], a[ndx0]
end
return a
end

– shuffle animalNames table
shuffle (animalNames)

[/code] [import]uid: 13507 topic_id: 8189 reply_id: 308189[/import]

Python has a shuffle method built in, too bad Lua doesn’t. Oh well, when I just searched “lua shuffle table” this was the second result:
http://www.gammon.com.au/forum/?id=9908

That said, this isn’t how I would approach the problem anyway. I would put the filenames into numbered table entries and then access them using a random number. So like:

[code]
animalNames = {}
animalNames[1] = “animal-duck-1.png”
animalNames[2] = “animal-frog-1.png”
etc

img = newImage(animalNames[math.random(animalNames#)])
[/code] [import]uid: 12108 topic_id: 8189 reply_id: 29205[/import]

That shuffle method at gammon.com.au doesn’t fully work, you can most clearly see if it the table only has 2 items. Here is a fixed version of the Fisher–Yates shuffle (use at your own risk of course):

[code]
function shuffleArray(array)
 local arrayCount = #array
 for i = arrayCount, 2, -1 do
 local j = math.random(1, i)
 array[i], array[j] = array[j], array[i]
 end
 return array
end
[/code]

[import]uid: 10284 topic_id: 8189 reply_id: 52756[/import]

The below code works well :

[code]
local function shuffle(t)
local rand = math.random
assert(t, “table.shuffle() expected a table, got nil”)
local iterations = #t
local j

for i = iterations, 2, -1 do
j = rand(i)
t[i], t[j] = t[j], t[i]
end
end
[/code] [import]uid: 84637 topic_id: 8189 reply_id: 52771[/import]

Is local rand = math.random faster?

BTW, I wonder if the assert could be amended to assert(type(t) == 'table', ...) or something [import]uid: 10284 topic_id: 8189 reply_id: 52777[/import]

Localizing things is faster. You probably wont notice a difference though unless you are doing a lot of complex math functions. [import]uid: 84637 topic_id: 8189 reply_id: 52779[/import]

Just a programatic thought. Shuffling is different that randomly selecting an item from a table. You need to shuffle when you plan on consuming items in the list. Like a deck of cards, once you pull one out of the deck to deal it, your card count goes down and no one else can get that card. Doing random entries from a table doesn’t accomplish the same thing.
The way I do this: Copy the table to a temporary table, then randomly remove items from temp table and adding them the shuffled table that will be returned to the caller. That way, they keep the original un-shuffled table around in case they need to re-shuffle later. The caller gets the shuffled table back and then as you use an item from the table you remove it, reducing the number of items in the table (taking a card from the deck).

I’m building a shuffle module. Right now it just builds a table of random numbers. I plan on expanding this to pass in a table and return a shuffled table.

module(..., package.seeall)  
  
function numbers(entries)  
  
 local tmpArray = {}  
 local shuffledArray = {}  
 local i  
 for i = 1, entries do  
 tmpArray[i] = i  
 end  
  
 math.randomseed(os.time()) -- reseed the random number generator  
 local random = math.random  
  
 for i = 1, entries do  
 local idx = random(#tmpArray)  
 shuffledArray[i] = tmpArray[idx]  
 table.remove(tmpArray,idx)  
 end  
 return shuffledArray  
end  

To use:

  
local shuffle = require("shuffle")  
  
local arrayOfShuffledNumbers = {}  
arrayOfShuffledNumbers = shuffle.numbers(10)  
  

[import]uid: 19626 topic_id: 8189 reply_id: 52804[/import]

you should try:

[code]

table.shuffle = function (t)
local n = #t
while n > 2 do
local k = math.random(n)
t[n], t[k] = t[k], t[n]
n = n - 1
end
end

[/code] [import]uid: 68741 topic_id: 8189 reply_id: 52806[/import]

Notts_forest, that shuffle function contains a bug and doesn’t work as expected… it needs to be “while n >= 2” not “while n > 2” to really shuffle all items… [import]uid: 10284 topic_id: 8189 reply_id: 52839[/import]

do you have to localize certain functions like

[lua]local rand = math.random
local value = rand(1,10)[/lua]

will it cause any kind of memory leak if I just put

[lua]local value = math.random(1,10)[/lua]

Thanks [import]uid: 39370 topic_id: 8189 reply_id: 98065[/import]