选择正确的物品基于luck值Lua

假设我有这个表格。

Config.LootboxesRewards = {
    [1] = {
        {name = 'a45amg',               label = '梅赛德斯A45 AMG',    amount = 1,     type = '车辆',   luck = 3},
        {name = '720s',                 label = '720s迈凯伦',         amount = 1,     type = '车辆',   luck = 20},
        {name = 'bac2',                 label = 'bac2',                 amount = 1,     type = '车辆',   luck = 20},
        {name = 'm6prior',              label = '宝马M6',               amount = 1,     type = '车辆',   luck = 19},
        {name = 'huracan',              label = '兰博基尼Huracan',  amount = 1,     type = '车辆',   luck = 19},
        {name = 'yzfr6',                label = '雅马哈R6',            amount = 1,     type = '车辆',   luck = 19},
    },
}

基于此,我想根据该表格上的luck值为玩家提供1个物品。 最好的方法是什么?

原文链接 https://stackoverflow.com/questions/70113418

点赞
stackoverflow用户2858170
stackoverflow用户2858170

最简单的方法是使用 math.random(#Config.LootboxesRewards[1]) 索引 Config.LootboxesRewards[1]

这假设你只想给玩家一个随机的物品,并且概率是均匀分布的。如果你想要变化获取特定物品的概率,建议从这里开始:

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

阅读:

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

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

2021-11-25 15:59:26
stackoverflow用户4515989
stackoverflow用户4515989

一种简单的解决方案是在战利品表中比概率较低的物品(较低的运气值)更频繁地放置概率较高的值(较高的运气值)。

您仍然可以保留表格以方便使用,并像这样预处理表格:

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 = '赛车',    amount = 1,     type = 'car',   luck = 3},
        {name = '720s',                 label = '麦拉伦720S',         amount = 1,     type = 'car',   luck = 20},
        {name = 'bac2',                 label = 'bac2',                 amount = 1,     type = 'car',   luck = 20},
        {name = 'm6prior',              label = '宝马M6',               amount = 1,     type = 'car',   luck = 19},
        {name = 'huracan',              label = '兰博基尼Huracan',  amount = 1,     type = 'car',   luck = 19},
        {name = 'yzfr6',                label = '雅马哈R6',            amount = 1,     type = 'car',   luck = 19},
    }
})

然后您可以从表格中选择一个随机索引以找到奖励:

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)

编辑: 如果您希望相反的情况(较高的运气=放弃的机会较小),则您可以改变这两个函数:

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
2021-11-25 16:56:57
stackoverflow用户1514861
stackoverflow用户1514861

如果幸运就是被选中的几率,那么幸运值为10的车辆比幸运值为5的车辆有两倍的被选中几率,你可以像这样做:

function pickBasedOnLuck(list)
    local totalLuck = 0
    for i, car in ipairs(list) do
        totalLuck = totalLuck + car.luck
    end
    local pick = math.random(totalLuck)
    for i, car in ipairs(list) do
        if pick > car.luck then
            pick = pick - car.luck
        else
            return car
        end
    end
end

所以在你的情况下,可以像这样调用它 pickBasedOnLuck(Config.LootboxesRewards[1])

2021-11-26 09:32:54