How to randomize a table

I am using a table of position for a Mine Spawner in a tower defense game.

I call the table every 5 seconds to give me a random position on the Mob Path.

Currently the table plays from first to last everytime its called, resulting in the mines spawning in the same position every time.

How do I randomize the table when it is called?

This is the parts of the script involving the table:

Summary
local function newPoint()
	for _, pointList in pairs(mathPoints) do
		if #pointList > 2 then
			local firstPoint = pointList[math.random(#pointList)].Position

			local isStraight = true

			for i, point in ipairs(pointList) do
				if i > 1 then
					local direction = (point.Position - firstPoint).Unit

					local dotProduct = math.abs(direction:Dot((pointList[i-1].Position - firstPoint).Unit))

					if dotProduct < .99 then -- not within 2 degrees of each other, so not straight line
						isStraight = false
						break;
					end

				end

			end

			if isStraight then
				--get random location between 2 points
				print(pointList)
				minePosition = firstPoint + (pointList[#pointList].Position - firstPoint) * math.random()

				break;
			end

		end

	end
end


while true do 
	--spawn mine every 5 seconds
	wait(1)
	
	if minePosition then
		print(minePosition)
		local newMine = mine:Clone()
		newMine.Parent = tower
		
		newMine.PrimaryPart.Position = minePosition 
	end
	newPoint()
end
2 Likes

Please try researching a bit before creating a topic next time. Hopefully this topic can help.

1 Like

I actually tried this before posting :wink:

local function shuffle(tableToShuffle: table): table
		local ShuffledTable = {}

		for Index = 1, #mathPointsdo
			local RandomIndex = math.random(#mathPoints)
			table.insert(ShuffledTable , mathPoints[RandomIndex])
			table.remove(mathPoints, RandomIndex)
		end
		
		print(ShuffledTable)
		
		return ShuffledTable 
	end
	
	shuffle(mathPoints)

It doesn’t seem to work for me? print(ShuffledTable)
image

Use a Fisher-Yates shuffle:

Code:

local function shuffle(t)
	local j, temp
	for i = #t, 1, -1 do
		j = math.random(i)
		temp = t[i]
		t[i] = t[j]
		t[j] = temp
	end
	
	return t
end

shuffle(mathPoints)
print(mathPoints)
1 Like

This may be an issue with the structure of my table, but it doesn’t seem to work either.

why dont you just randomise the index?

local array = {1, 2, 3, 4, 5}
local index = math.random(1, #array)

print(array[index])

Sorry but I don’t really understand so well how tables work.

How would I incorporate this into my table?

for _, pointList in pairs(mathPoints) do
		if #pointList > 2 then
			local firstPoint = pointList[math.random(#pointList)].Position

			local isStraight = true

			for i, point in ipairs(pointList) do
				if i > 1 then
					local direction = (point.Position - firstPoint).Unit

					local dotProduct = math.abs(direction:Dot((pointList[i-1].Position - firstPoint).Unit))

					if dotProduct < .99 then -- not within 2 degrees of each other, so not straight line
						isStraight = false
						break;
					end

				end

			end

			if isStraight then
				--get random location between 2 points
				minePosition = firstPoint + (pointList[#pointList].Position - firstPoint) * math.random()

				break;
			end

		end

	end

The mathPoints table needs randomized before this section of code, or within the for do loop if possible?

I’m pretty sure the temp variable isn’t needed in Lua because it’s possible to change/swap 2 values at once:

local function shuffle(t)
	for i = #t, 1, -1 do
		local j = math.random(i)
		t[i], t[j] = t[j], t[i]
	end
end

shuffle(mathPoints)
print(mathPoints)

Also as @TaxFraudBruh mentioned you can just randomize the indexes when picking the items:

local availableIndexes = {}
for i = 1, #mathPoints do table.insert(availableIndexes, i) end

for i = 1, #mathPoints do
	local index = availableIndexes[math.random(#availableIndexes)]
	print(index, mathPoints[index])
end
1 Like

This returns the same table as @Katrist’s solution

I know, I just mentioned that the temp variable wasn’t needed and the function size could be reduced.

1 Like

This wouldn’t randomize it, but this should swap the order of the table right?

if sortOrder == "a" then
		table.sort(mathPoints, function(a,b)
			return a[2] > b[2]
		end)
		print("A", mathPoints)
		sortOrder = "b"
	else
		table.sort(mathPoints, function(a,b)
			return a[2] < b[2]
		end)
		print("B", mathPoints)
		sortOrder = "a"
	end

For some reason this returns the same table.
image