How to not choose the last thing you chose in math.random

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)

113432117783744626

And I want this

139472529104635179

2 Likes

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
1 Like
-- 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
1 Like

How would I reference the newest stage? Like, turned the cloned stage into a variable.

I did this

local newStage = getNewStage()

Idk if that is what im supposed to do but it does not shuffle them.

1 Like