盲盒开盒核心算法

关于盲盒开盒相关的流程介绍,请查阅我的另一篇文章

——盲盒想中大奖?还不如去买彩票!!!——从程序的角度揭秘盲盒

盲盒规则概率 实体类

 1 /**
 2  * 盲盒规则概率 实体
 3  * @author JustJavaIt
 4  * @date 2022/01/29 14:18
 5  */
 6 @Data
 7 public class BlindBoxRule {
 8 
 9     private Long id;
10 
11     /**
12      * 盲盒ID
13      */
14     private Long boxId;
15 
16     /**
17      * 盲盒商品类型(1至尊,2超稀有,3稀有,4普通)
18      */
19     private Integer label;
20 
21     /**
22      * 概率
23      */
24     private Integer realRate;
25 
26     public BlindBoxRule(Long id, Long boxId, Integer label, Integer realRate) {
27         this.id = id;
28         this.boxId = boxId;
29         this.label = label;
30         this.realRate = realRate;
31     }
32 
33     /**
34      * 根据用户抽的盲盒id为19,查询出对应商品类型的概率值。
35      * 补充说明:每个盲盒id都有4种商品类型(1至尊,2超稀有,3稀有,4普通),有不同的概率。每种类型下有不同的商品。
36      * @return
37      */
38     public static List<BlindBoxRule> queryByBoxId(){
39         List<BlindBoxRule> boxRuleList = new ArrayList<>();
40         BlindBoxRule rule1 = new BlindBoxRule(1L, 19L, 1, 200);
41         BlindBoxRule rule2 = new BlindBoxRule(1L, 19L, 2, 600);
42         BlindBoxRule rule3 = new BlindBoxRule(1L, 19L, 3, 3200);
43         BlindBoxRule rule4 = new BlindBoxRule(1L, 19L, 4, 96000);
44         boxRuleList.add(rule1);
45         boxRuleList.add(rule2);
46         boxRuleList.add(rule3);
47         boxRuleList.add(rule4);
48 
49         return boxRuleList;
50     }
51 }

盲盒开盒核心算法类

 1 /**
 2  *  盲盒开盒核心算法
 3  *  需求说明:盲盒id为19(19.手机,20.手办等)中有四种商品类型(1.至尊,2.超稀有,3.稀有,4.普通),至尊抽中的概率为0.02%,超稀有抽中的概率为0.06%,稀有抽中的概率为3.2%,普通抽中的概率为96%;
 4  * @author JustJavaIt
 5  * @date 2022/01/29 10:47
 6  */
 7 public class BlindBoxDraw {
 8     public static void main(String[] args) {
 9 
10         //模拟数据,根据用户抽的盲盒id=19(前端传),查询对应盲盒id下商品类型((1.至尊,2.超稀有,3.稀有,4.普通))的概率
11         List<BlindBoxRule> blindBoxRules = BlindBoxRule.queryByBoxId();
12 
13         //将商品概率添加到集合中,用于下面抽奖
14         List<Integer> probList = new ArrayList<>(blindBoxRules.size());
15         for (BlindBoxRule rule : blindBoxRules) {
16             probList.add(rule.getRealRate());
17         }
18 
19         //开盒核心方法
20         int drawResult = draw(probList);
21         System.out.println("draw返回值为:" + drawResult);
22 
23         //注意List下标从0开始
24         switch (probList.get(drawResult)){
25             case 200:  System.out.println("恭喜你抽中至尊款商品"); return;
26             case 600: System.out.println("恭喜你抽中超稀有款商品"); return;
27             case 3200: System.out.println("恭喜你抽中稀有商品"); return;
28             case 96000: System.out.println("恭喜你抽中普通款商品"); return;
29             default: System.out.println("异常");
30         }
31 
32         //实际业务中根据命中的商品类型((1.至尊,2.超稀有,3.稀有,4.普通))获得该类型下对应的商品(手机,平板等),每个商品也有一个权重值,也是通过类似上面的draw()抽取商品后,再判断用户是否符合一些别的门槛,符合的话就算开箱完成。
33     }
34 
35     /**
36      *  大致流程说明:计算出的sortRateList里面的概率有四个,0.0002,0.0006,0.032,0.96,随机生成的浮点数在0-1内,假如随机数为0.2546,
37      *  那么sortRateList排序后为0.0002,0.0006,0.032,0.2546,0.96,那么返回的索引sortRateList.indexOf(random)就是4,既抽中的类型为普通款
38      * @param probList
39      * @return
40      */
41     public static int draw(List<Integer> probList) {
42         //最终加入随机值后排序的集合
43         List<Double> sortRateList = new ArrayList<>();
44 
45         // 计算概率总和
46         Integer sumRate = 0;
47         for (Integer prob : probList) {
48             sumRate += prob;
49         }
50 
51         if (sumRate != 0) {
52             // 概率所占比例
53             double rate = 0D;
54             for (Integer prob : probList) {
55                 rate += prob;
56                 // 构建一个比例区段组成的集合(避免概率和不为1)
57                 sortRateList.add(rate / sumRate);
58             }
59 
60             // 随机生成一个随机数,并排序
61             ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
62             //生成0-1之间的Double类型随机数 eg:0.7570711......
63             double random = threadLocalRandom.nextDouble(0, 1);
64             System.out.println("生成的随机数值为:" + random);
65             sortRateList.add(random);
66             Collections.sort(sortRateList);
67             System.out.println("排序后的sortRateList为:" + sortRateList.toString());
68 
69             // 返回该随机数在比例集合中的索引
70             return sortRateList.indexOf(random);
71         }
72 
73         return -1;
74     }
75 }

 <END>

⭐️希望本文章对您有帮助,您的「 转发、点赞 是我创作的无限动力。

扫描下方二维码关注微信公众号,您会收到更多优质文章推送。

 

 

 

 

 

posted @ 2022-01-30 10:47  JustJavaIt  阅读(1846)  评论(1编辑  收藏  举报