lua实现游戏抽奖的几种方法
^_^内容原创,禁止转载
假设配置如下:
local reward_pool = {
{weight = , item = {, num = }},
{weight = , item = {, num = }},
{weight = , item = {, num = }},
{weight = , item = {, num = }},
{weight = , item = {, num = }},
{weight = , item = {, num = }},
}
1.顺序查找,预处理时间复杂度O(n),抽奖最坏情况O(n)
--预处理
local N = #reward_pool
for _, v in ipairs(reward_pool) do
total_weight = total_weight + v.weight
end
--实现
local rand_weight = math.random(total_weight)
local reward_index
for k, v in ipairs(reward_pool) do
_total_weight = _total_weight + v.weight
if _total_weight >= rand_weight then
reward_index = k
break
end
end
2.按照离散思路进行分割,二分查找,预处理时间复杂度O(n),抽奖最坏情况O(logn)
--预处理
local N = #reward_pool
for _, v in ipairs(reward_pool) do
com_weight = com_weight + v.weight
v.weight = com_weight
end
--实现
, #reward_pool
while right >= left then
)
local mid_weight = reward_pool[mid].weight
if value == mid_weight then
right = right -
break
elseif value < mid_weight then
right = mid -
else
left = mid +
end
end
right = right + --此时right为reward_pool中抽到的索引
这种方法在实际上是对第一种方法的优化,在大多数情况下都可以取代第一种方法,但取舍还要看实际情况,一个极端且明显的例子如下:
local reward_pool = {
{weight = , item = {, num = }}, {weight = , item = {, num = }},
{weight = , item = {, num = }}, {weight = , item = {, num = }},
{weight = , item = {, num = }}, {weight = , item = {, num = }},
{weight = , item = {, num = }}, {weight = , item = {, num = }},
{weight = , item = {, num = }}, {weight = , item = {, num = }},
}
3.AliasMethod,个人实现的预处理O(3n),抽奖时间复杂度O(1),下面是实现过程,证明日后有时间再整理给出
queue = {}
function queue:new()
, last = -}
self.__index = self
setmetatable(res, self)
return res
end
function queue:push(value)
self.last = self.last +
self[self.last] = value
end
function queue:pop()
local first = self.first
if first > self.last then
self.first =
self.last = -
return nil
end
local value = self[first]
self[first] = nil
self.first = self.first +
return value
end
function queue:front()
return self[self.first]
end
--预处理
local N = #reward_pool
for _, v in ipairs(reward_pool) do
total_weight = total_weight + v.weight
end
local Prob = {}
local Alias = {}
local weightN_queue_L = queue:new()
local weightN_queue_U = queue:new()
for k, v in ipairs(reward_pool) do
local weight_N = v.weight * N
if weight_N == total_weight then
Prob[k] = weight_N
else
local tb = {index = k, value = weight_N}
local qu = weight_N > total_weight and weightN_queue_U or weightN_queue_L
qu:push(tb)
end
end
while true do
local l_qu = weightN_queue_L:pop()
if not l_qu then
break
end
local u_qu = weightN_queue_U:front() --或直接pop,比total_weight大再push回去
Prob[l_qu.index] = l_qu.value
Alias[l_qu.index] = u_qu.index
u_qu.value = u_qu.value + l_qu.value - total_weight
if u_qu.value < total_weight then
weightN_queue_U:pop()
weightN_queue_L:push(u_qu)
elseif u_qu.value == total_weight then
weightN_queue_U:pop()
Prob[u_qu.index] = total_weight
end
end
weightN_queue_U = nil
weightN_queue_L = nil
--实现
local n = math.random(N)
local weight = math.random(total_weight)
local reward_index = weight > Prob[n] and Alias[n] or n
lua实现游戏抽奖的几种方法的更多相关文章
- 【转载】解决繁体、日文游戏乱码的五种方法 转载自:http://tieba.baidu.com/p/488627981
方法1:转换区域 开始——设置——控制面板——区域和语言选项——分别选择“高级”和“区域选项”标签——在其下拉框中都选择“日语”(或“日本”)(选项有点多,慢慢找)——重启后即可生效. *某影注:日语 ...
- Unity3d获取游戏对象的几种方法
1.GameObject.Find() 通过场景里面的名子或者一个路径直接获取游戏对象. GameObject root = GameObject.Find("GameObject" ...
- 游戏对象消失三种方法的区别?(enabled/Destroy/active)
gameObject.renderer.enabled=fasle是控制一个物体是否在屏幕上渲染或显示 而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的GameObject.De ...
- slua中,绑定lua文件到Monobehavior的一种方法
slua本身并不提供如何把一个lua文件绑定到一个预制中,就像一个普通的继承自monobehavior的自定义脚本那样,而tolua的框架却采用了拙劣的做法: public class LuaBeha ...
- unity3d 游戏对象消失三种方法的区别(enabled/Destroy/active)
gameObject.renderer.enabled //是控制一个物体是否在屏幕上渲染或显示 而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的 GameObject.Destr ...
- 【Cocos2d-x游戏开发】解决Cocos2d-x中文乱码的三种方法
众所周知,Cocos2d-x是一款不错的开源引擎,但是在Cocos2d-x中直接使用中文是无法正确显示的.比如下面的情况: 解决这个问题常用的有三种方法:1.通过转换为UTF-8编码来显示.2.使用i ...
- C模块回调Lua函数的两种方法
作者:ani_di 版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di C模块回调Lua函数的两种方法 lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平 ...
- [Unity3D]Unity3D游戏开发Lua随着游戏的债券(于)
---------------------------------------------------------------------------------------------------- ...
- lua中 table 重构index/pairs元方法优化table内存占用
转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...
随机推荐
- 一篇漫画故事带你理解透HTTPS(上)
2020年蝙蝠纪元,二毛一如往常的呆在家中,不敢外出去浪. 为排解心中之闷,二毛抽了一口老烟,熟练的打开了全球最大的同性交友网站,准备假装了解下最近流行的项目... 只听啪的一声回车键,哪知浏览器蹦出 ...
- [vijos1782]借教室<线段树>
题目链接:https://vijos.org/p/1782 题意:一个区间1,n.m次操作,每次操作让l,r区间值减去d,当有任何一个值小于0就输出当前是第几个操作 这道题其实是没有什么难度的,是 ...
- 解决Python pip安装第三方包慢的问题
解决Python pip安装第三方包慢的问题 主要是修改源,国内的源有几个 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi ...
- 你还不知道Vue的生命周期吗?带你从Vue源码了解Vue2.x的生命周期(初始化阶段)
作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...
- Spring ApplicationContext 容器
Spring ApplicationContext 容器 Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文. Application Con ...
- vue+springboot后台实现页面按钮权限
思路 1.用户跟角色关联 2.角色跟菜单关联 3.菜单跟菜单下的按钮关联 4.后端返回每个菜单下的按钮,前端通过自定义事件,在每个按钮上加上相应的事件 打字麻烦,还是看图吧! 建立btn.js 然后在 ...
- python编程笔记整理(2)
1.向字典中添加元素 字典名[键名] = 键值 my["姓名"] = "许嘉祺" (使用此代码可以把键值对添加到名为name的字典里.) (由于 ...
- udev规则,部署Multipath
部署Multipath多路径环境 配置iSCSI服务 编写udev规则 配置并访问NFS共享 部署Multipath多路径环境 1 配置iSCSI服务 1.1 问题 本案例要求先搭建好一台iSCSI服 ...
- 「给产品经理讲JVM」:垃圾收集算法
纠结的我,给我的JVM系列终于起了第三个名字,害,我真是太难了.从 JVM 到 每日五分钟,玩转 JVM 再到现在的给产品经理讲 JVM ,虽然内容为王,但是标题可以让更多的人看到我的文章,所以,历经 ...
- Mac osx下误删了mach_kernel文件,如何找回
brew install xar 假设当前有一个 pkg 文件"filename.pkg",先使用以下命令解开 pkg: $ xar -xf filename.pkg 解压后发现其 ...