I am making an infinite runner type game and I use randomized models to make the map. To randomize them I do this:
local newStage = script:GetChildren()[math.random(1, #script:GetChildren())]:Clone()
But sometimes it chooses something it just chose, which makes the map look very repetitive. How would I make it so that it cannot choose what it has chosen right before that.
Just to make sure that made sense this is my map rn (Each number representing a piece of the map)
Create a table. Every time you generate the number, save the number in a variable instead of doing it while picking the object in :GetChildren. Before the newStage variable, write an if statement to check if that new variables of the random number is already in the table. If it is, put the rest of your code (from the newStage variable down) into it.
It should look something like this:
local alreadyPicked = {}
local randomNumber = math.random(1, #script:GetChildren())
if not alreadyPicked[randomNumber] then
-- Your code goes here
else
table.insert(alreadyPicked, randomNumber)
return
end
-- Decently efficient
local lastStageIdx = nil
function getNewStage()
local stages = script:GetChildren()
local stageIdx
repeat
stageIdx = math.random(1, #stages)
until stageIdx ~= lastStageIdx
lastStageIdx = stageIdx
return stages[stageIdx]:Clone()
end
-- Proper Shuffling
local lastStageIdx = nil
local shuffled = {}
function shuffle()
local stages = script:GetChildren()
for i = 1, #stages do
shuffled[i] = i
end
for i = #stages, 2, -1 do
local j = math.random(1, i)
shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
end
end
function getNewStage()
if #shuffled == 0 then
shuffle()
end
local stageIdx = table.remove(shuffled, 1)
lastStageIdx = stageIdx
return script:GetChildren()[stageIdx]:Clone()
end