游戏抽奖活动中下限保底的简单实现

  同事说:“下限保底就是前多次不出第一次,前多少次不出第二次等等。第一次接触下限保底时没有理解什么意思,因为我"前多次"理解错了,我把它理解成了“该道具被抽中了前多少次”,但实际“前多少次”就是指玩家抽奖抽了多少次。搞清楚这一点后下限保底就很简单了。

  项目中下限保底就是这样实现的,挺简单的。首先就是要记录玩家抽奖的次数。然后配置需要下限保底的道具。最后根据玩家的抽奖次数判断被保底的道具能不能给玩家。由于很简单,直接贴Lua脚本的代码了。

--[[
日期:2014年2月12日
程序:游戏中下限抽奖保底。
]]


-------------------------------------------------------
--配置
ProbabilityConf = 
{
	--[[下限保底说明:对于指定道具,前多次肯定不出第1次,前多少次肯定不出第2次,...]]
	lowerItems = 
	{
		{
			id = 117,
			--[[说明:前5次肯定不出第1次,前10次肯定不出第2此,前13次肯定不出第3次,后面便没有限制]]
			grade = {5, 10, 13,},
		},
		{
			id = 118,
			grade = {15, 25, 35, 40, 60, },
		},
	},

	--[[抽奖物品,由于取的是[1,10000]内的一个随机数,所以物品的总rate值需要是10000。重要的物品配置两端,
	    道具配置的顺序需要考虑抽中保底物品时,如果此次物品被保底则不能被抽取,返回下一个道具时应返回一个很普通道具。]]
	rewards = 
	{
		--[[{id = 111, name = "item_111", rate = 100, },
		{id = 112, name = "item_112", rate = 200, },
		{id = 113, name = "item_113", rate = 300, },
		{id = 114, name = "item_114", rate = 400, },
		{id = 115, name = "item_115", rate = 1000, },
		{id = 116, name = "item_116", rate = 1100, },]] --物品少一点,重要的物品概率配置大一点,为了测试
		{id = 119, name = "item_119", rate = 1000, },
		{id = 117, name = "item_117", rate = 4000, },
		{id = 118, name = "item_118", rate = 4000, },
		{id = 120, name = "item_120", rate = 1000, }, --这样是一个普通道具,保底物品不能被选中时,就会返回这个物品
	},
}


-------------------------------------------------------
--脚本
ProbabilityFunc = {}

ProbaData = {} 	--用于存放数据
--[[
ProbaData.Lower[id]: 记录id被抽中的次数。
ProbaData.LoterryTimes: 玩家总的抽奖次数。
]]

--函数:设置随机值的seed。
ProbabilityFunc.InitRandom = function(seed)
	local 	curTime = os.time()
	seed = seed or curTime

	--print("ProbabilityFunc.InitRandom: seed = "..seed)
	math.randomseed(seed)
end


--[[
函数:返回一个在[min, max]区间内的随机数。
]]
ProbabilityFunc.GetRandomNumber = function(min, max)
	local 	random = math.random(min, max)

	--print("ProbabilityFunc.GetRandomNumber: random = "..random)
	return random
end


--[[
函数:查看index是否是下限保底物品。liyan
返回:
 参数1: true/nil。
]]
ProbabilityFunc.IsLowerItem = function(id)
	for _, one in ipairs(ProbabilityConf.lowerItems) do
		if one.id == id then 
			return one
		end
	end
	return
end


--[[
函数:index对应的物品是否可以被抽取。
返回:
 参数1: true/nil,true表示物品可以被抽取,nil表示不能被抽取。
]]
ProbabilityFunc.CanBeGiven = function(id)
	--是否是下限保底物品
	local 	oneLower = ProbabilityFunc.IsLowerItem(id)
	if not oneLower then return true end

	local 	lowerIndex = ProbaData.Lower[id]
	local 	needChouJiangTime = oneLower.grade[lowerIndex+1]
	--print("lowerIndex = "..lowerIndex)
	--print("needChouJiangTime = "..needChouJiangTime)
	--print("ProbaData.LoterryTimes = "..ProbaData.LoterryTimes)
	if not needChouJiangTime then return true end  	--已经突破了下限保底

	--大于配置中的值,才可以被抽取
	return needChouJiangTime < ProbaData.LoterryTimes
end


--[[
函数:本次抽奖获得的物品。
返回:
 参数1: ProbabilityConf.rewards中的索引。
]]
ProbabilityFunc.GetItem = function()
	local 	random = ProbabilityFunc.GetRandomNumber(1, 10000)
	print("ProbabilityFunc.GetItem: random = "..random)
	
	local 	value, index = 0, 0
	for i, itemInfo in ipairs(ProbabilityConf.rewards) do
		index = i
		value = value + itemInfo.rate
		if value >= random and ProbabilityFunc.CanBeGiven(itemInfo.id) then
			--print("ProbabilityFunc.GetItem: i = "..i)
			return i 
		end
	end

	return index
end


--函数:根据index打印物品信息。
ProbabilityFunc.PrintItem = function(index)
	local 	itemInfo = ProbabilityConf.rewards[index]

	if not itemInfo then 
		print("ProbabilityFunc.PrintItem: invalid index "..index)
		return 
	end

	local 	str = string.format("you have id = %d, name = %s", itemInfo.id, itemInfo.name)
	print(str)
end


--函数:一次抽奖结束后,记录一些信息。
ProbabilityFunc.RecordAfter = function(index)
	--记录玩家抽奖次数
	ProbaData.LoterryTimes = ProbaData.LoterryTimes + 1

	--记录保底物品被抽中
	local 	itemInfo = ProbabilityConf.rewards[index]
	if itemInfo then 
		if ProbaData.Lower[itemInfo.id] then
			ProbaData.Lower[itemInfo.id] = ProbaData.Lower[itemInfo.id] + 1
		end
	end
end


--函数:抽奖业务。
ProbabilityFunc.Lottery = function(num)
	local 	str = string.format("you have %d times", num)
	print(str)

	for i = 1, num do
		local 	index = ProbabilityFunc.GetItem()
		ProbabilityFunc.RecordAfter(index)

		ProbabilityFunc.PrintItem(index)
	end

	--debug,不需要的话,可以注释掉此函数的调用
	ProbabilityFunc.Debug()
end


--函数:初始化数据。
ProbabilityFunc.InitData = function()
	ProbaData.Lower = {}

	for _, oneItem in ipairs(ProbabilityConf.lowerItems) do
		ProbaData.Lower[oneItem.id] = 0
	end
	ProbaData.LoterryTimes = 0
end


ProbabilityFunc.Debug = function()
	print("\n-----ProbabilityFunc.Debug----")

	local 	str = string.format("DEBUG: you have loterry %d times", ProbaData.LoterryTimes)
	print(str)
	for _, oneItem in ipairs(ProbabilityConf.lowerItems) do
		print(oneItem.id, ProbaData.Lower[oneItem.id])
	end

	print("-----ProbabilityFunc.Debug----\n")
end


--函数:初始化
ProbabilityFunc.Init = function()
	ProbabilityFunc.InitRandom()
	ProbabilityFunc.InitData()
end


--函数:脚本入口函数
ProbabilityFunc.main = function()
	ProbabilityFunc.Init()

	local 	read
	while true do
		print("Enter a number to start, or 'quit' to exit:")
		read = io.read()
		if read == "quit" then break end
		--------------------------------------------
		
		ProbabilityFunc.Lottery(tonumber(read))
		print()
	end

	print("Exit!!!")
end


ProbabilityFunc.main()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值