js抽奖发红包算法(奖项权重+金额范围随机,支持小数)

前言

近期需要为平安普惠公众号开发一个抽奖发红包的需求,在抽奖页面的下方需要滚动展示用户中奖信息,如下图所示
在这里插入图片描述
由于活动参与的人数多,并发量高,为了减轻服务器的访问压力,决定前端用js算法来随机生成用户中奖记录。

一、抽奖需求

1、抽奖金额权重

  • 1~200元,中奖概率为20%,记为一等奖
  • 0.5~1元,中奖概率为20%,记为二等奖
  • 0.3~0.5元,中奖概率为60%,记为三等奖

2、金额要取奖项范围的随机值

  • 假如用户中的是一等奖,则金额为1~200元的随机值,如23.89元
  • 假如用户中的是二等奖,则金额为0.5~1元的随机值,如0.8元
  • 假如用户中的是三等奖,则金额为0.3~0.5的随机值,如0.34元

二、算法实现

1、计算用户中了几等奖

  • 抽奖方法,接收奖项参数
// 抽奖方法
function Draw(prizes) {
	var prizeList = [] //按照权重分解后的奖品数组
	prizes.map(function(item) {
		prizeList.push({
			name : item.name,
			value : item.key
		})
		for (var i = 0; i < item.probability; i++) {
			prizeList.push({
				name : item.name,
				value : item.key
			})
		}
	});
	prizeList = reset(prizeList);
	// 范围随机数
	function randomFrom(lowerValue, upperValue) {
		return Math.floor(Math.random() * (upperValue - lowerValue + 1)
				+ lowerValue);
	}
	;
	// 随机打乱数组
	function reset(arr) {
		var eachArr = arr.concat([])
		var lastArr = []
		function deepEach(deepArr) {
			if (deepArr.length) {
				var randomIndex = randomFrom(0, eachArr.length - 1)
				lastArr.push(eachArr[randomIndex])
				eachArr.splice(randomIndex, 1)
				deepEach(eachArr)
			}
		}
		deepEach(eachArr)
		return lastArr
	}
	this.getResult = function() {
		var random = randomFrom(0, prizeList.length - 1);
		return prizeList[random]
	}
}
  • 奖项数据结构
// 奖项和概率数据结构,probability 为中奖概率,可以根据实际需求修改
var model = [ {
	name : '一等奖',
	key : 'level1',
	probability : 20,
}, {
	name : '二等奖',
	key : 'level2',
	probability : 20,
}, {
	name : '三等奖',
	key : 'level3',
	probability : 60,
} ]

2、生成相应奖项的随机金额

//生成从minNum到maxNum的随机数
function randomNum(maxNum, minNum, decimalNum) {
    // 获取指定范围内的随机数, decimalNum指小数保留多少位
    var max = 0,
        min = 0;
    minNum <= maxNum ? (min = minNum, max = maxNum) : (min = maxNum, max = minNum);
    switch (arguments.length) {
        case 1:
            return Math.floor(Math.random() * (max + 1));
            break;
        case 2:
            return Math.floor(Math.random() * (max - min + 1) + min);
            break;
        case 3:
            return (Math.random() * (max - min) + min).toFixed(decimalNum);
            break;
        default:
            return Math.random();
            break;
    }
}

3、抽奖

window.onload = function() {
			
	// 创建抽奖对象
	var draw = new Draw(model);
	// 抽奖100次
	var total = 100;
	// 中一等奖个数
	var first = 0;
	// 中二等奖个数
	var second = 0;
	// 中三等奖个数
	var third = 0;
	// 中奖结果
	var results = new Array(total);
	for(var i=0;i<total;i++){		
		// 获取中了几等奖
		var drawResult = draw.getResult();
		// 生成相应奖项的随机金额
		var value = 0;
		if (drawResult.name == '一等奖') {
			// 1-200,两位小数
			value = randomNum(1,200,2);
			first++;
		} else if (drawResult.name == '二等奖') {
			// 0.5-1,两位小数
			value = randomNum(0.5,1,2);
			second++;
		} else if (drawResult.name == '三等奖') {
			// 0.3-0.5,两位小数
			value = randomNum(0.3,0.5,2);
			third++;
		}
		results[i] = value;
	}
	console.log("results:" + results);
	console.log("total:" + total);
	console.log("first:" + first + ",比例:" + (first / total));
	console.log("second:" + second + ",比例:" + (second / total));
	console.log("third:" + third + ",比例:" + (third / total));
};

抽奖100次结果如下
在这里插入图片描述

写在最后

虽然本文通过js实现了随机抽奖算法,但仅仅是用于伪数据展示,如果项目要求数据必须真实,还是需要通过后台实现。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值