Help with weighted chances

Hello, I’m trying to make a system where a number (1-20) is selected. But I don’t want each number to have the name chance. I know a lot of people say that the odds must add up to 1 or 100% but I know there’s a way you can work around that. I’ve looked into Weighted Chances but I can’t get it to work for me.

Im hoping to achieve a system where I can draw one of these numbers from the table below with their respective chances, Also it should always them one number.
(also dont mind the * luck thats just so I can alter the players luck)

local LuckOdds = {
	[1] = 30 * luck;
	[2] = 10 * luck;
	[3] = 2 * luck;
	[4] = 0.5 * luck;
	[5] = 0.23 * luck;
	[6] = 0.12 * luck;
	[7] = 0.0777 * luck;
	[8] = 0.045 * luck;
	[9] = 0.018 * luck;
	[10] = 0.0086 * luck;
	[11] = 0.002  * luck;
	[12] = 0.00066 * luck;
	[13] = 0.00041 * luck;
	[14] = 0.00017 * luck;
	[15] = 0.000096 * luck;
	[16] = 0.000053 * luck;
	[17] = 0.0000302 * luck;
	[18] = 0.0000099 * luck;
	[19] = 0.0000066 * luck;
	[20] = 0.000001 * luck;
}

Oh and here’s my current script with its output:

local Button = script.Parent

local luck = 1
local weight = 0

--//Odds:
local LuckOdds = {
	*Hidden To save space*
}

function GetRNG()
	for _, Chance in pairs(LuckOdds) do
		weight += (Chance * 10)
	end
	
	local ranNumber = math.random(1, weight)
	
	weight = 0
	for	Chosen, Chance in pairs(LuckOdds) do
		weight += (Chance * 10)
		
		if weight >= ranNumber then
			print('RNG: '..ranNumber)
		end
	end
end

Button.MouseButton1Click:Connect(function()
	GetRNG()
end)

image

2 Likes

It seems that you are trying to implement a weighted random selection system, where each number between 1 and 20 has a different chance of being selected based on its weight.

local LuckOdds = {
	[1] = 30;
	[2] = 10;
	[3] = 2;
	[4] = 0.5;
	[5] = 0.23;
	[6] = 0.12;
	[7] = 0.0777;
	[8] = 0.045;
	[9] = 0.018;
	[10] = 0.0086;
	[11] = 0.002;
	[12] = 0.00066;
	[13] = 0.00041;
	[14] = 0.00017;
	[15] = 0.000096;
	[16] = 0.000053;
	[17] = 0.0000302;
	[18] = 0.0000099;
	[19] = 0.0000066;
	[20] = 0.000001;
}


local total_weight = 0
for _, weight in pairs(LuckOdds) do
    total_weight = total_weight + weight
end


for i, weight in pairs(LuckOdds) do
    LuckOdds[i] = weight / total_weight
end


function GetRNG()
    local threshold = math.random()
    local accumulated_weight = 0
    
    for i, weight in pairs(LuckOdds) do
        accumulated_weight = accumulated_weight + weight
        if accumulated_weight >= threshold then
            print('Chosen number: ' .. i)
            break
        end
    end
end
6 Likes

So with this script there would be a 0,000001% chance to get the number 20?

Yes, that’s correct. The chance of getting the number 20 is equal to the weight assigned to it, which is 0.000001. When you divide the weights by the total weight, you are essentially converting them into probabilities. So in this case, the probability of getting the number 20 would be 0.000001.

1 Like

Alright, Thank you so much for your help.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.