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 ...
随机推荐
- ThreadAbortException是可以传递的
今天在写线程Aborted代码时,发现嵌套的try catch中的ThreadAbortException错误是可以从内部传递到外部的,想想这也是必然的,在内部该线程已经中断了,外部必然是中断了,再仔 ...
- [vijos1162]波浪数
题目链接:https://www.vijos.org/p/1162 这题的解法我觉得可能是模拟吧,但是题的分类又是构造QAQ..... 不是很懂,所以我们把这个方法叫做奇技淫巧吧 这题的暴力思路就是针 ...
- JavaScript登录记住密码操作
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- 字符串操作 — Google Guava
前言 Java 里字符串表示字符的不可变序列,创建后就不能更改.在我们日常的工作中,字符串的使用非常频繁,熟练的对其操作可以极大的提升我们的工作效率,今天要介绍的主角是 Google 开源的一个核心 ...
- 统计分析_集中趋势and离散程度
1.数组的集中趋势-如何定义数组的中心 1.1 常用几下几个指标来描述一个数组的集中趋势 均值-算术平均数 . 中位数-将数组升序或降序排列后,位于中间的数. 众数-数组中出现最多的数. 1.2 指标 ...
- Vue-CLI 3.x 自动部署项目至服务器
前言 平时部署前端项目流程是:先部署到测试环境ok后再发布到生产环境上,部署到测试环境用 xshell 连上服务器,然后用 xftp 连接服务器,然后本地 build 项目,接着把 build 好的文 ...
- GitHub+PicGo构建免费图床及其高效使用
搭建免费图床全过程! 一.搭建缘由 一开始搭建博客,避免不了要用许多图片,最初使用七牛云来做博客图床,但是后来发现,七牛云只有30天的临时域名,hhhhhhh,果然啊,天下就没有免费的好事啊~后来就发 ...
- sprigboot 异常 Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].Tomc...
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...
- webWMS开发过程记录(二)- WMS是什么
(参考:WMS-百度百科) 简介 WMS是仓库管理系统(Warehouse Management System)的缩写,是一款标准化.智能化过程导向管理的仓库管理软件仓库管理系统,是通过出入库业务.仓 ...
- stand up meeting 12/22/2015 && 用户体验收录
part 组员 工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 完善页面切换,尝试子页面设计 4 完善页面切换和子页面 ...