|
@@ -0,0 +1,172 @@
|
|
|
+package com.iohao.mmo.equip.service;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author 唐斌
|
|
|
+ * @date 2023-08-31
|
|
|
+ * @description:
|
|
|
+ */
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.concurrent.ThreadLocalRandom;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author:linxu
|
|
|
+ * @Date:2020-7-24 00:09:54
|
|
|
+ */
|
|
|
+public class WeightRandomTemplate2 {
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ List<DefaultWeightWrap> rewardWraps = new ArrayList<>();
|
|
|
+ rewardWraps.add(new RewardWrap(12881, "一等奖", 1, 1, 5));
|
|
|
+ rewardWraps.add(new RewardWrap(12882, "二等奖", 1, 2, 10));
|
|
|
+ rewardWraps.add(new RewardWrap(12883, "三等奖", 1, 3, 25));
|
|
|
+ //默认奖励,如果抽不到奖,默认抽中安慰奖【参与奖】
|
|
|
+ RewardWrap rewardWrap = new RewardWrap(12884, "安慰奖", 1, 4, 60);
|
|
|
+ rewardWraps.add(rewardWrap);
|
|
|
+
|
|
|
+ WeightRandom<DefaultWeightWrap> weightRandom = new WeightRandom<>(rewardWraps, rewardWrap);
|
|
|
+ int num1Count = 0;
|
|
|
+ int num2Count = 0;
|
|
|
+ int num3Count = 0;
|
|
|
+ int num4Count = 0;
|
|
|
+ //模拟抽奖二十次【第一种方式调用】
|
|
|
+ for (int i = 0; i < 1000000; i++) {
|
|
|
+ RewardWrap rewardWrapRandom = (RewardWrap) weightRandom.randomWeightWrap();
|
|
|
+ if(rewardWrapRandom.rank==1){
|
|
|
+ num1Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==2){
|
|
|
+ num2Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==3){
|
|
|
+ num3Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==4){
|
|
|
+ num4Count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println(num1Count+"---"+num2Count+"---"+num3Count+"---"+num4Count);
|
|
|
+ int num11Count = 0;
|
|
|
+ int num12Count = 0;
|
|
|
+ int num13Count = 0;
|
|
|
+ int num14Count = 0;
|
|
|
+ //模拟抽奖二十次【第二种方式调用】
|
|
|
+ for (int i = 0; i < 1000000; i++) {
|
|
|
+ RewardWrap rewardWrapRandom = (RewardWrap) weightRandom(new IWeightRandom<DefaultWeightWrap>() {
|
|
|
+ @Override
|
|
|
+ public List<DefaultWeightWrap> applyWraps() {
|
|
|
+ return rewardWraps;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public DefaultWeightWrap applyDefaultWrap() {
|
|
|
+ return rewardWrap;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if(rewardWrapRandom.rank==1){
|
|
|
+ num11Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==2){
|
|
|
+ num12Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==3){
|
|
|
+ num13Count++;
|
|
|
+ }else if(rewardWrapRandom.rank==4){
|
|
|
+ num14Count++;
|
|
|
+ }
|
|
|
+// System.out.println(rewardWrapRandom.toString());
|
|
|
+ }
|
|
|
+ System.out.println(num11Count+"----"+num12Count+"----"+num13Count+"----"+num14Count);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //测试实现类
|
|
|
+ public static class RewardWrap extends DefaultWeightWrap {
|
|
|
+ private int rewardId;//奖励id
|
|
|
+ private String rewardName;//奖励名称
|
|
|
+ private int rewardValue;//数量
|
|
|
+ private int rank;//奖励排名1等奖,2等奖
|
|
|
+ public RewardWrap(int rewardId, String rewardName, int rewardValue, int rank, int weight) {
|
|
|
+ this.rewardName = rewardName;
|
|
|
+ this.rewardValue = rewardValue;
|
|
|
+ this.rewardId = rewardId;
|
|
|
+ this.rank = rank;
|
|
|
+ this.weight = weight;
|
|
|
+ }
|
|
|
+ public int getRewardId() {
|
|
|
+ return rewardId;
|
|
|
+ }
|
|
|
+ public void setRewardId(int rewardId) {
|
|
|
+ this.rewardId = rewardId;
|
|
|
+ }
|
|
|
+ public int getRank() {
|
|
|
+ return rank;
|
|
|
+ }
|
|
|
+ public void setRank(int rank) {
|
|
|
+ this.rank = rank;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return "Reward{" +
|
|
|
+ "rewardId=" + rewardId +
|
|
|
+ ", rewardName='" + rewardName + '\'' +
|
|
|
+ ", rewardValue=" + rewardValue +
|
|
|
+ ", rank=" + rank +
|
|
|
+ '}';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方式1【创建对象调用的方式】
|
|
|
+ *
|
|
|
+ * @param <T>
|
|
|
+ */
|
|
|
+ public static class WeightRandom<T extends DefaultWeightWrap> {
|
|
|
+ private List<T> content;//目标集合数据
|
|
|
+ private T defaultResult;//默认返回值【参与奖励】
|
|
|
+
|
|
|
+ public WeightRandom(List<T> content, T defaultResult) {
|
|
|
+ this.content = content;
|
|
|
+ this.defaultResult = defaultResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T randomWeightWrap() {
|
|
|
+ int s = content.stream().mapToInt(DefaultWeightWrap::getWeight).sum();
|
|
|
+ int r = ThreadLocalRandom.current().nextInt(s);
|
|
|
+ Optional<T> o = content.stream().filter(t -> {
|
|
|
+ int result = r - t.getWeight();
|
|
|
+ return result < 0;
|
|
|
+ }).findFirst();
|
|
|
+ return o.orElse(defaultResult);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 方式2【静态方法,内部实现接口方式的调用】
|
|
|
+ *
|
|
|
+ * @param iWeightRandom
|
|
|
+ * @param <T>
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static <T extends DefaultWeightWrap> T weightRandom(IWeightRandom<T> iWeightRandom) {
|
|
|
+ int s = iWeightRandom.applyWraps().stream().mapToInt(DefaultWeightWrap::getWeight).sum();
|
|
|
+ int r = ThreadLocalRandom.current().nextInt(s);
|
|
|
+ Optional<T> o = iWeightRandom.applyWraps().stream().filter(t -> { int result = r - t.getWeight();return result < 0; }).findFirst();
|
|
|
+ return o.orElse(iWeightRandom.applyDefaultWrap());
|
|
|
+ }
|
|
|
+ public interface IWeightRandom<T extends WeightRandomTemplate2.DefaultWeightWrap> {
|
|
|
+ List<T> applyWraps();//目标集合数据
|
|
|
+
|
|
|
+ T applyDefaultWrap();//默认返回值【参与奖励】
|
|
|
+ }
|
|
|
+
|
|
|
+ //权重包装基类
|
|
|
+ public static abstract class DefaultWeightWrap {
|
|
|
+ public int weight;//权重
|
|
|
+
|
|
|
+ public int getWeight() {
|
|
|
+ return weight;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return "DefaultWeightWrap{" +
|
|
|
+ "weight=" + weight +
|
|
|
+ '}';
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|