最近在写一个游戏中中奖的随机概率算法,暂时的要求有如下:
- 若干个奖项之中,需要选择其中的4个
- 每个奖项的概率都需要随时可以调整
- 调整概率的时候,不要太麻烦,可以相对来调整,比如想调整奖项1和奖项2是1:2的关系
想了想,就写了下算法,记录下,别忘记了
因为是写游戏,所以逻辑是用lua写的,说实话,lua真的是太难嚼了,身为脚本语言,却没有脚本语言的各种语法糖,硬生生的用底层语言的方式来作出了脚本语言的特性,而且对go to Definition一点都不友好
-- key是商品名称, value是概率
-- 比例不需要加起来等于1,根据需要随意调整
local probs = {
["总额*2"] = 0.9,
["总额*5"] = 0.7,
["总额*10"] = 0.1,
["总额*20"] = 0.03,
["总额*50"] = 0.005,
["次数*5"] = 0.8,
["次数*10"] = 0.7,
["次数*15"] = 0.1,
["次数*20"] = 0.03,
}
function Choose(probs)
local total = 0;
for _, value in pairs(probs) do
total = total + value
end
--- 根据总和生成一个随机值,然后根据区间段来定位,区间段短的,分到的几率就低
local randnum = math.random() * total
for key, value in pairs(probs) do
if randnum <= value then
return key
else
randnum = randnum - value
end
end
end
-- table 拷贝,用到lue wiki(http://lua-users.org/wiki/)上的片段
function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
-- 需要4个值,所以就打印4次,因为不能重复,所以每次取值就去掉已选的值
local probs_cp = shallowcopy(probs)
for i = 1, 4, 1 do
value = Choose(probs_cp)
probs_cp[value] = nil
print(value)
end
用上面这个算法,从宏观来说,概率确实的按照要求来的,当然实际过程中,random的随机种子不要每次都一样
打印结果如下
次数*5
总额*2
总额*5
次数*10