 # Weighted Random

I want to create a function that will return an item from a table where the item has a certain chance of being returned.

I already found some stuff about weighted random functions and tutorials on the DevForum, but none have been very clear on how exactly I can achieve this.

`math.random` gives all items in a table the same chance of being picked, instead, I want something like this:

``````local OrderedTable = {
["This is very common"] = 80, -- 80 percent chance this value is returned
["This is less common"] = 30, -- 30 percent chance this value is returned
["This is very uncommon"] = 10 -- 10 percent chance this value is returned
}
``````

What you can do is something like this. Use math.random to get a random number from 1-100. Then have three if statements, one checking if the number is <= 80, another if its > 80 and <= 95, and another if its > 95.

You can adjust the numbers to whatever chance you want but you get the idea. The numbers in your example don’t add up to 100% so I made up some numbers as an example.

2 Likes

It doesn’t have to add up to 100, basically, all common stuff gets a high number, and the less common stuff will get a lower number.

I’m looking for a more efficient way of doing this, I’ll be using this on a table that could get 100+ items, it’s not feasible to spaghetti code 100 if’s and add more code every time I create a new item.

I actually believe there are existing posts on this topic that might help you:)

1 Like

Just got it working, some DevForum posts about this were a bit unclear, but in my code, there was another factor that made it look like it wasn’t actually working.

I changed this code a bit to get the following function:

``````function WeightedRandom:RandomFromWeightedTable(OrderedTable)
local TotalWeight = 0

for Piece, Weight in pairs(OrderedTable) do
TotalWeight = TotalWeight + Weight
end

local Chance = math.random(1, TotalWeight)
local Counter = 0
for Piece, Weight in pairs(OrderedTable) do
Counter = Counter + Weight
if Chance <= Counter then
return Piece
end
end
end
``````

OrderedTable must look like this:

``````local OrderedTable = {
["item"] = PickChanceIn%
}
``````
2 Likes