幸运大转盘抽奖逻辑实现
2023-02-26 12:27:08 时间
@[toc]
1. 需求
(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>)
如图,实现一个转盘抽奖,
有个n个奖项,每个奖项配置中奖概率,点击开始抽奖进行抽奖;
本文主要讲后端抽奖逻辑算法;
2. 实现思路
2.1 实现逻辑步骤
- 前端使用现有的转盘插件 如 https://github.com/LuckDraw/vue-luck-draw
- 后台能够添加配置抽奖的奖项,以及每个奖项的名称、数量、中奖概率
- 前端调用接口查询所有奖项,初始化转盘
- 点击开始抽奖,调用后端接口,接口计算中奖概率得到中奖奖项,返回中奖的奖项给前端,前端提示中奖
2.2 计算中奖概率算法
下面会贴出概率计算的代码,封装成了工具类,可以直接在项目里面用;
这里讲思路。
举例: 奖项及中奖概率 苹果 10%,橘子 20%, 香蕉 15%, 柠檬 5%, 谢谢参与 35%
- 根据奖项概率生成区间(从0开始,累加当前奖项的概率)
分别如下:
苹果 [0,10) 橘子 [10,30) 香蕉 [30,45) 柠檬 [45,50) 谢谢参与 [50,85)
- 生成随机数,落在哪个区间,就返回对应的中奖项
3. 实现代码
调用方式
public static void main(String[] args) { //实际上我们的奖项可能是个实体类;这面的map就是HashMap<奖项类, Integer> HashMap<String, Integer> map = new HashMap<>(); map.put("苹果", 10); map.put("橘子", 20); map.put("香蕉", 15); map.put("柠檬", 5); map.put("波罗", 15); map.put("谢谢参与", 35); //直接调用工具类 RandomUtil WeightMeta<String> md = RandomUtil.buildWeightMeta(map); //md.random()的结果就是奖项; System.out.println("恭喜你抽到了:"+md.random()); }
概率计算工具类,调用方式参考里面的main方法
RandomUtil.java
public class RandomUtil { /*** * @param weightMap key是奖项,value是概率 * @param <T> * @return */ public static <T> WeightMeta<T> buildWeightMeta(final Map<T, Integer> weightMap) { final int size = weightMap.size(); Object[] nodes = new Object[size]; int[] weights = new int[size]; int index = 0; int weightAdder = 0; for (Map.Entry<T, Integer> each : weightMap.entrySet()) { nodes[index] = each.getKey(); weights[index++] = (weightAdder = weightAdder + each.getValue()); } return new WeightMeta<T>((T[]) nodes, weights); } }
奖项权重计算类
WeightMeta.java
package com.happy.netshop.wechat.helper; import java.util.Arrays; import java.util.Random; public class WeightMeta<T> { private final Random ran = new Random(); private final T[] nodes; private final int[] weights; private final int maxW; public WeightMeta(T[] nodes, int[] weights) { this.nodes = nodes; this.weights = weights; this.maxW = weights[weights.length - 1]; } /** * 该方法返回权重随机对象 * @return */ public T random() { int index = Arrays.binarySearch(weights, ran.nextInt(maxW) + 1); if (index < 0) { index = -1 - index; } return nodes[index]; } public T random(int ranInt) { if (ranInt > maxW) { ranInt = maxW; } else if(ranInt < 0){ ranInt = 1; } else { ranInt ++; } int index = Arrays.binarySearch(weights, ranInt); if (index < 0) { index = -1 - index; } return nodes[index]; } @Override public String toString() { StringBuilder l1 = new StringBuilder(); StringBuilder l2 = new StringBuilder("[random]t"); StringBuilder l3 = new StringBuilder("[node]tt"); l1.append(this.getClass().getName()).append(":").append(this.hashCode()).append(":n").append("[index]tt"); for (int i = 0; i < weights.length; i++) { l1.append(i).append("t"); l2.append(weights[i]).append("t"); l3.append(nodes[i]).append("t"); } l1.append("n"); l2.append("n"); l3.append("n"); return l1.append(l2).append(l3).toString(); } }
4. 其它问题处理
实际上抽奖并不是公平的按照概率去抽的;会有一些黑幕操作在里面;
例如:
4.1 奖项设置有次数限制
例如 个别奖项,设置三天内只能抽到2次
思路1: 简单点直接存redis,抽中的时候存入redis,记录次数,key到期时间设置3天;抽中的时候获取redis存的次数,判断达到2次,就直接返回谢谢参与 思路2: 存数据库,抽中的时候查询三天内已经抽中的次数,大于2次就直接返回谢谢参与奖项
4.2 奖项设置有总数量
例如 个别奖项,设置总共有5个
跟上边思路是一样的;做好库存管理,没有数量了就返回谢谢参与
4.3 让大奖在前半段时间内不被抽到
实现思路就是: 1. 默认概率最低的奖项就是大奖或者在后台配置得知哪个是大奖; 2. 如果抽到的是大奖,则计算当前时间是否在整个活动时间的1/2时间内,如果是的话,就返回谢谢参与
5.总结
这里主要是记录下这次做的功能,以后用到了可以直接使用上面的工具类计算概率,比较方便。
你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:
相关文章
- Jgit的使用笔记
- 利用Github Action实现Tornadofx/JavaFx打包
- 叹息!GitHub Trending 即将成为历史!
- 微软软了?开源社区讨论炸锅,GitHub CEO 亲自来答
- GitHub Trending 列表频现重复项,前后端都没去重?
- Photoshop Elements 2021版本软件安装教程(mac+windows全版本都有)
- (ps全版本)Photoshop 2020的安装与破解教程(mac+windows全版本都有)
- (ps全版本)Photoshop cc2018的安装与破解教程(mac+windows全版本,包括2023
- 环境搭建:Oracle GoldenGate 大数据迁移到 Redshift/Flat file/Flume/Kafka测试流程
- 每个开发人员都要掌握的:最小 Linux 基础课
- 来撸羊毛了!Windows 环境下 Hexo 博客搭建,并部署到 GitHub Pages
- 超实用!手把手入门 MongoDB:这些坑点请一定远离
- 【GitHub日报】22-10-09 zustand、neovim、webtorrent、express 等4款App今日上新
- 【GitHub日报】22-10-10 brew、minio、vite、seaweedfs、dbeaver 等8款App今日上新
- 【GitHub日报】22-10-11 cobra、grafana、vue、ToolJet、redwood 等13款App今日上新
- Photoshop 2018 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2017 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2020 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2023 资源免费下载(mac+windows全版本都有,包括最新的2023)
- 最新版本Photoshop CC2018软件安装教程(mac+windows全版本都有,包括2023