This isn’t actually that hard of a problem, but let’s simplify it a little bit first.
Instead of saying that green and blue have a 25% chance and red a 50% chance, let’s give green and blue a value of 1, and red a value of 2. This value will represent how many times the colour appears in our list, so currently it’d look like this: GBRR
where G = green, B = blue, R = red.
If you now select a random value out of this list, you will have a greater chance of selecting red than green and blue.
A simple program that might achieve this could be written as follows, although I don’t recommend using it:
local list = {red = 2, green = 1, blue = 1}
local function selectItem(list)
local newList = {}
for color, count in pairs(list) do
for i = 1, count do
table.insert(newList, color)
end
end
-- newList is now {"red", "red", "green", "blue"}
local item = newList[math.random(#newList)]
return item
end
print(selectItem(list))
This is actually what you want to achieve, but you can improve it a lot more.
Creating a new table, increasing it’s size everytime it gets filled, and moving all values inside can take a lot of time. Additionally, you’d also like to give items half the chance of being selected, and multiplying all values besides that one by 2 is simply tedious.
What you can do instead is count up all the values of each item, and generate a random number between 0 and that. After that, you can find the item that corresponds to that value.
local list = {red = 2, green = 1, blue = 0.5}
local function selectItem(list)
local count = 0
for _, value in pairs(list) do
count += value
end
local number = math.random() * count
-- math.random(x) generates a whole number between 0 and x
-- math.random() * x generates a more random number between 0 and x
-- Select the item
count = 0
for item, value in pairs(list) do
if (count < number) and (count + value >= number) then
return item
end
count += value
end
end
print(selectItem(list))
I have not tested this code, but this should return red 2 times as often as green, and green 2 times as often as blue.