Trying to make a reward with probability

I am trying to give the player a reward with probability but it does not work as expected

It is based on a probability of 0 to 1, the problem is that it only returns 2 probabilities (the one of 0.800 and 0.500) and the rest never returns

This is the code:

local Rewards = {    
    {"Coins", 50, 0.800};
    {"Coins", 150, 0.500};
    {"Coins", 500, 0.310};
    {"Gems", 200, 0.100};
    {"Gems", 500, 0.035};
};

script.Parent.MouseButton1Click:Connect(function()
    local randomChance = math.random();
    local cumulativeChance = 0;
    
    for i, v in pairs(Rewards) do
        local Currency = v[1];
        local Reward = v[2];
        local Chance = v[3];
        
       cumulativeChance = cumulativeChance + Chance;
        
        if randomChance <= cumulativeChance and #v > 0 then
            print("You win", Reward, Currency, "The chance was", Chance)
            break
        end
    end
end)

I really appreciate if you could help me fix this problem, thanks for reading! :slight_smile:

1 Like

Its probably because you used “break”, remove it and it will probs work.

It can’t be that, the break makes me choose the reward

You could do this instead of a for loop:

local randomReward = Rewards[randomChance]
local currency = randomReward[1]
local reward = randomReward[2]
local chance = randomReward[3]

and try doing this in the randomChance

local randomChance = math.random(#Rewards)

I could do that but it’s not exactly what I want, I want this to have a “%” chance that it will give you that reward, if I do what you told me it would be much easier to get the hardest reward to get

The first one is 0%-80%, and the next is 80%-130%. You’re not going to ever get higher than 100%, so any other numbers won’t matter once you get to the one going up till 100%.

2 Likes

Here is my way of selecting things by chance:

local random = math.random(1,100)

if (random <= 30) then -- 30% chance

elseif (random > 30) then -- 70% chance

end

You don’t need the elseif, just else, and this is exactly what the person is doing already. They just did it wrong by creating probabilities over 1 (100%) so nothing else would ever be picked.

1 Like

math.random() with no arguments returns a number between 0 and 1 (I think).

I think its also possible to do:

local rand = Random.new(tick())
local sumOfAllChances
rand:NextNumber(0,sumOfAllChances)

You need to make so all the chances adding up equal to 1.

To convert your current chances to that (though it may not be accurate so I recommend doing it manually).

Take the sum of all the chances:
0.8+0.5+0.31+0.1+0.035

=

1.745

Divide every chance with 1.745 and set it as the new chance.

0.8/1.745

Do it with all the chances and it should work as expected, but still I recommend deciding all the chances again and make sure they add up to 1.

1 Like

yes i know that’s the reason why it doesn’t work but i can’t think of what to do to make it throw all the odds

Just have them add up to 100%. If you really can’t, multiply your random number by whatever they add up to (e.g. 1.745 here).

3 Likes

You can try something like this:

local sum = 0
for _, item in ipairs(choices) do
    sum += item.Weight
end

local rand = math.random(sum)
for _, item in ipairs(choices) do
    if rand < item.Weight then
        return item.Object
    end

    rand -= item.Weight
end

Example of “choices”:

local choices = {
    {Weight = 50, Object = "ok"},
    {Weight = 25, Object = "ok1"},
    {Weight = 25, Object = "ok2"},
}

algorithm is from here: c++ - Weighted random numbers - Stack Overflow

I’d recommend calculating the sum of the weights a single time instead every single time you need to pick, given that the choices are going to be the same each time. Make sure you pick a new random number each time though.

This doesn’t use percentages so the weights don’t have to add up to a hundred each time. If they do, you can just set the sum of the weights to 100 instead of counting them each time.

2 Likes

It worked :smiley: , I did not want to break my head adding each Chance so that in the end it reaches 100% since I want to add +10 Rewards so thanks to the help of @strategic and @rog I managed it, thanks for helping!

btw, the algorithm also served :slight_smile: