Hereâs another idea you can play around with. Rather than relying on fixed percents for the value in the chances dict, it treats those numbers as ratios. So, if there were 3 items in the list that had equal probability, then they would each have the same value. In your given chances dict, the values as ratios are 60:32:7:1, since the total is 100, then the chances of ea are 60/100, 32/100, 7/100, 1/100 or 60%, 32%, etc. You donât need the values in the chances dict to be percents (portions of 100) though; would work fine with other ratios like 1:1:1, which would become 1/3, 1/3, 1/3 or 33%, 33%, 33% as the odds.
Can think of this code as working like a wheel. Each item in your chances dictionary is a wedge on the wheel and its size is proportional to the odds that it will be picked. Something like this if the âwheelâ were linear (letters rep ea item in the list).
0 [L][..R..][........J........][....................S....................] 100
when a rand number is picked between the start and end values (0 and 100 in this case), where it falls determines which item is selected. Since âSâ , here, takes up the most space in that range, it is the most likely to be picked.
local CHANCES = {
SpeedBoost = 60,
JumpBoost = 32,
Regen = 7,
LowGravity = 1,
}
local sumOfChances -- could be pre-calculated and stored in constant
-- uses const CHANCES dict
local function getSumOfChances()
local sum = 0
for k,v in pairs(CHANCES) do
sum += v
end
return sum
end
-- uses const CHANCES dict
local function spinTheWheel(sumOfChances)
local randValue = Random.new():NextNumber(0.0, sumOfChances)
local runningCount = 0
for k,v in pairs(CHANCES) do
runningCount += v
if randValue < runningCount then
return k
end
end
end
Example
-- test
sumOfChances = getSumOfChances()
testDict = {}
for i = 1, 1000 do
local val = spinTheWheel(sumOfChances)
if testDict[val] == nil then
testDict[val] = 1
else
testDict[val] += 1
end
end
for k,v in pairs(testDict) do
print(k,v)
end
An advantage of this kind of approach is that you donât necessarily have to change all the values when you add a new item to the chances list. For example, lets say we start with two items that are common and equally likely to be chosen. We could assign ea of them the value 100. In that case, the spinner would choose a rand nbr between 0 and 200 with 0-100 going to the first and 1-200 to the second. If we wanted to add a new item that was twice as likely to be chosen as our baseline items, then it could be given the value 200 and the others would stay as they are. If a fourth item was only 1% as likely to be chosen as one of our two baseline items, then it would be given a value of 1. This makes rare items VERY rare as the number of items in the list increases. To combat that you could spin twice: once for a category (rare vs common vs uncommon), then again for a specific item in the category.
Anyway, just some additional ideas. GL with your game!