Home > OS >  Choose the correct item based on luck Lua
Choose the correct item based on luck Lua

Time:11-26

Lets say I have this table.

Config.LootboxesRewards = {
    [1] = {
        {name = 'a45amg',               label = 'Mercedes A45 AMG ',    amount = 1,     type = 'car',   luck = 3},
        {name = '720s',                 label = '720s mclaren',         amount = 1,     type = 'car',   luck = 20},
        {name = 'bac2',                 label = 'bac2',                 amount = 1,     type = 'car',   luck = 20},
        {name = 'm6prior',              label = 'BMW M6',               amount = 1,     type = 'car',   luck = 19},
        {name = 'huracan',              label = 'Lamborghini Huracan',  amount = 1,     type = 'car',   luck = 19},
        {name = 'yzfr6',                label = 'Yamaha R6',            amount = 1,     type = 'car',   luck = 19},
    },
} 

Based on that I would like to give the the player 1 item based on luck value on that table. What is the best way to do it?

CodePudding user response:

The simplest way is to index Config.LootboxesRewards[1] with math.random(#Config.LootboxesRewards[1])

This assumes that you just want to give your player a random item with uniform distribution. If you want to vary the chanc of getting particular items I suggest you start here:

https://en.wikipedia.org/wiki/Probability

Read:

https://www.lua.org/manual/5.4/manual.html#pdf-math.random

https://www.lua.org/manual/5.4/manual.html#pdf-math.randomseed

CodePudding user response:

One simple solution is to put the values with a higher chance (higher luck value) more often in the loot-table than the items with a lower change (lower luck value).

You can still keep your table for convenience and pre-process the table like this:

local function gcd(a, b)
    while a ~= b do
        if a > b then
            a = a - b
        else
            b = b - a
        end
    end

    return a
end

local function gcd_tbl(values, value_getter)
    if #values < 1 then
        return nil
    end

    value_getter = value_getter or function(v) return v end

    local result = value_getter(values[1])

    for i = 2, #values do
        result = gcd(result, value_getter(values[i]))
    end

    return result
end

local function process_rewards(tbl)
    local result = {}

    for id, rewards in pairs(tbl) do
        result[id] = {}

        local greatest_common_divisor = gcd_tbl(rewards, function(v) return v.luck end)

        for _, reward in ipairs(rewards) do
            for i = 1, reward.luck / greatest_common_divisor do
                table.insert(result[id], reward)
            end
        end
    end

    return result
end

Config.LootboxesRewards = process_rewards({
    [1] = {
        {name = 'a45amg',               label = 'Mercedes A45 AMG ',    amount = 1,     type = 'car',   luck = 3},
        {name = '720s',                 label = '720s mclaren',         amount = 1,     type = 'car',   luck = 20},
        {name = 'bac2',                 label = 'bac2',                 amount = 1,     type = 'car',   luck = 20},
        {name = 'm6prior',              label = 'BMW M6',               amount = 1,     type = 'car',   luck = 19},
        {name = 'huracan',              label = 'Lamborghini Huracan',  amount = 1,     type = 'car',   luck = 19},
        {name = 'yzfr6',                label = 'Yamaha R6',            amount = 1,     type = 'car',   luck = 19},
    }
})

You can then choose a random index from the table to find the reward:

function get_random_reward(lootbox_id)
    local lootbox_rewards = Config.LootboxesRewards[lootbox_id]
    if not lootbox_rewards then
        return nil
    end

    return lootbox_rewards[math.random(#lootbox_rewards)]
end

get_random_reward(1)

EDIT: If you wish to indicate the other way around (higher luck = less chance to drop), you could chance these 2 functions:

local function gcd_and_max_tbl(values, value_getter)
    if #values < 1 then
        return nil, nil
    end

    value_getter = value_getter or function(v) return v end

    local value = value_getter(values[1])
    local gcd_result, max_result = value, value

    for i = 2, #values do
        value = value_getter(values[i])
        gcd_result = gcd(gcd_result, value)
        max_result = math.max(max_result, value)
    end

    return gcd_result, max_result
end

local function process_rewards(tbl)
    local result = {}

    for id, rewards in pairs(tbl) do
        result[id] = {}

        local greatest_common_divisor, max_luck = gcd_and_max_tbl(rewards, function(v) return v.luck end)
        local max_relevant_luck = max_luck / greatest_common_divisor

        for _, reward in ipairs(rewards) do
            for i = 1, max_relevant_luck - (reward.luck / greatest_common_divisor)   1 do
                table.insert(result[id], reward)
            end
        end
    end

    return result
end
  • Related