Can't get weighted chance for table in RNG type game

I struggled a bit to find the answer for you, but I believe what you’re looking for is inverted probability

Here’s the code, I tested and it works pretty well:

M = {}

-- Define the items with their weights
M.items = {
	{"Common", 2}, {"Uncommon", 4}, {"Good", 5}, {"Natural", 10},
	{"Rare", 16}, {"Divinus", 32}, {"Crystalized", 64}, {"Rage", 128},
	{"Topaz", 150}, {"Ruby", 350}, {"Forbidden", 404}, {"Emerald", 500},
	{"Gilded", 512}, {"Ink", 700}, {"Jackpot", 777}, {"Sapphire", 800},
	{"Aquamarine", 900}, {"Wind", 912}, {"Diaboli", 1004}, {"Precious", 1024},
	{"Glock", 1700}, {"Magnetic", 2048}, {"Glacier", 2304}, {"Sidereum", 4096},
	{"Bleeding", 4444}, {"Zolar", 5000}, {"Pruner", 6000}, {"Stard", 6120},
	{"Broke", 8245}, {"Venus", 10000}, {"Marvs", 12000}, {"Jupiter", 15000},
	{"FootLettuce", 20000}, {"Cursed", 30000}, {"Astronomical", 50000},
	{"Graete", 75000}, {"Swung", 100000}, {"Treaded", 250000}, {"Broken", 500000},
	{"Chakim", 1000000}, {"Gunks", 1500000}, {"Mello", 5000000}, {"Bepsi", 10000000},
	{"NevaGunks", 50000000}, {"ALBRUKE", 100000000}, {"Storm", 600000000}, {"Bellins", 1000000000},
	{"???", 2000000000}
}

function M.getRandomItem()	
	local items = M.items
	
	local total_inverse = 0
	
	local inverses = {}

	-- Compute the inverse of each number
	for i, item in pairs(items) do
		inverses[i] = 1 / item[2]
		total_inverse = total_inverse + inverses[i]
	end

	-- Normalize these inverses to form a probability distribution
	local probabilities = {}
	for i, inv in pairs(inverses) do
		probabilities[i] = {inv / total_inverse, items[i]}
	end

	-- Use the probability distribution to randomly select a number
	local rand = math.random()
	local cumulative_probability = 0
	for i, prob in pairs(probabilities) do
		cumulative_probability = cumulative_probability + prob[1]
		if rand <= cumulative_probability then
			return prob[2] -- Return item 
		end
	end
end

EDIT: Try to balance the weight to how you want, because the higher weigh items haven’t showed up during 1000 iterations, unless that’s what you want – try playing with difference weigh values and adjust accordingly

1 Like