If you know you are going to need at most N numbers, you could pregenerate the random numbers and insert them in a table according to their value. Then your function randomly picks a number from that table and removes the number. Something like:
local rands = {}
local numRands = 100
-- populate table of random numbers
while #rands < numRands do
local r = math.random(1,1000)
rands[r]=r -- if duplicate, table stays same
end
local function getNeverSameRandom()
local index = math.random(1,numRands)
return table.remove(rands, index)
end
If you don't know how many to populate, then keep track via table:
local randsUsed = {}
local maxRand = 1000000 -- largest random # you want
local function getNeverSameRandom()
local rnd
repeat
rnd = math.random(1,maxRand)
until randsUsed[rnd] == nil
randsUsed[rnd] = rnd
return rnd
end
The problem of course is that if you call getNeverSameRandom many times, like half the max random number, your randsUsed table is going to get quite full, and the repeat-until is going to take longer and longer. Eventually, the table will be full, and the function will be in an infinite loop. You could easily check by keeping track with a counter, but you cannot use #randsUsed
because randsUsed
is a table with "holes" so the # operation can't be used. For example:
local randsUsedCount = 0
local function getNeverSameRandom()
if randsUsedCount == maxRand then
error("No more random #'s left in range 1-"..maxRand)
end
local rnd
repeat
rnd = math.random(1,maxRand)
until randsUsed[rnd] == nil
randsUsed[rnd] = rnd
randsUsedCount = randsUsedCount + 1
return rnd
end