How can I prevent getting duplicates from math.random

I never really had to do this or try to counter this but as more I get into loading screen development the more I realise that if you are working with lot’s of objects trying to load in randomly at same time you want to have less duplicates and more actual results

game.ReplicatedStorage.Events.LoadMap.OnClientEvent:Connect(function(Player)
	script.Parent.Enabled = true
	
	for i =1,51 do
		local random = script.Parent.Frame:GetChildren()
		local NewRandom = math.random(1,#random)
		local random2 = random[NewRandom]
		random2.BackgroundTransparency = 0
		wait()
	end
	
	wait(2)
	
	for i =1,51 do
		local random = script.Parent.Frame:GetChildren()
		local NewRandom = math.random(1,#random)
		local random2 = random[NewRandom]
		random2.BackgroundTransparency = 1
		wait()
	end
	script.Parent.Parent.Enabled = false
end)

This code gets anything in the frame and makes their transparency 0 so they appear on the screen for the player and does this again to remove it

1 Like

From what I understand, you’re trying to select two random, but different, values, from a set of values.

It can be simply done using tables:

-- the set of things we want to select from
local openSet = {"apple", "banana", "cherry", "durian"}

-- select a random thing from the table, remove it and save it into a variable
local firstThing = table.remove(openSet, math.random(#openSet))

-- repeat as many times as you want
local secondThing = table.remove(openSet, math.random(#openSet))
local thirdThing = table.remove(openSet, math.random(#openSet))

print(firstThing, secondThing, thirdThing)

The magic is in this part of the statement:

table.remove(openSet, math.random(#openSet))

Let’s dissect it! table.remove takes two parameters, a table and an index. It just removes the element at index from the table and returns it:

local numbers = {1, 2, 3, 4}
print(unpack(numbers)) --> 1 2 3 4

local aNumber = table.remove(numbers, 2) -- remove the 2nd element from numbers

print(unpack(numbers)) --> 1 3 4
print(aNumber) --> 2

For the table, we passed openSet. For the index, we passed math.random(#openSet). That simply selects a random number between 1 and #openSet (the number of things in openSet); that is, it selects a random index from openSet.

Hope that helps :slightly_smiling_face:

Im trying to make 51 thing’s transparency 1

You can use this to prevent duplicates:

repeat
    local number = math.random(1, #random)
    --Additional code
until number ~= alreadySelectedNumber -- Change alreadySelectedNumber to whatever the first random number is
3 Likes

I think I understand. You have a bunch of frames you want to make visible in a random order, and then make invisible again in a random order, right?

If so, then you can adapt the code samples I gave to do that:

local frames = script.Parent.Frame:GetChildren() -- get a list of all the frames

for index=1, #frames do -- from 1 to the number of frames (in your case, 51)
    local frame = table.remove(frames, math.random(#frames)) -- select a random frame and remove it from the list
    frame.BackgroundTransparency = 0 -- make that random frame opaque
    wait()
end

wait(2)

-- do the same thing, except making each frame transparent

frames = script.Parent.Frame:GetChildren()

for index=1, #frames do
    local frame = table.remove(frames, math.random(#frames))
    frame.BackgroundTransparency = 1
    wait()
end
5 Likes