根据运气 Lua 选择正确的项目

Posted

技术标签:

【中文标题】根据运气 Lua 选择正确的项目【英文标题】:Choose the correct item based on luck Lua 【发布时间】:2022-01-03 20:47:20 【问题描述】:

假设我有这张桌子。

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,
    ,
 

基于此,我想根据那张桌子上的运气值给玩家 1 件物品。 最好的方法是什么?

【问题讨论】:

“基于运气值”是什么意思?更高的运气是否意味着更少的机会?少了多少?玩家的运气如何发挥作用? 如果你滚动到我发布的那个表格的右边,你会看到有一个元素叫做luck 是的,但这意味着什么?较高的运气值是否意味着一辆稀有的汽车,一辆不太稀有的汽车?最简单的解决方案是找到最高公分,将运气值除以计算结果,然后将每个条目添加到临时表中的次数与计算结果相同。例如,如果您有luck=5 和luck=20,则最高公分是 5. 将第一项添加一次 (5/5=1) 到临时表,另一项添加 4 次 (20/5=4)。现在从该表中选择一个随机索引 运气不佳表明 cas 是否真的很好,例如梅赛德斯 A45 AMG,它是一款独特而稀有的汽车,这就是我们在那里拥有 3 个的原因。谢谢你的回答真的帮了我。 【参考方案1】:

最简单的方法是用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

【讨论】:

我使用数学随机,但我的问题是我可能有更多的值,同样的运气,最后我只需要返回所有这些中的 1 个。 我不知道你所说的“更多的价值和同样的运气”是什么意思。如果您只有一件物品要赠送,请在选择下一件物品之前从列表中删除该物品。运气不是数学的东西。请学习正确的术语。 你每次都会买车吗?获得超级跑车的概率是多少?如果你得到一辆,得到一辆特定超级跑车的概率是多少?如果你不理解这背后的数学,你就不可能对此建模。【参考方案2】:

一个简单的解决方案是在战利品表中更频繁地放置具有较高机会(较高运气值)的值,而不是具有较低变化(较低运气值)的物品。

为了方便起见,您仍然可以保留表格并像这样预处理表格:

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,
    
)

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

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)

编辑: 如果您希望反过来指出(运气越高 = 掉落的机会越少),您可以使用以下 2 个功能:

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

【讨论】:

【参考方案3】:

如果运气只是它被选中的可能性,那么运气 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])

【讨论】:

以上是关于根据运气 Lua 选择正确的项目的主要内容,如果未能解决你的问题,请参考以下文章

用 Lua 控制 MIDI 合成器来播放自定义格式乐谱

根据模板值在选择列表中设置所选项目

根据项目配置更改 csproj OutputType

OpenGL SDK如何使用Premake创建新项目

根据 .Net Core 构建选择正确的 Angular 环境

选择不依赖于状态的正确颤振块小部件