js抽奖算法

抽奖的核心算法

题目:设计一个js抽奖程序,一共分为三等奖,每一个等级的中奖概率及中奖人数都可自定义。

解法核心:

  • 设定概率

    • 一等奖概率:10%  即 [0 - 0.1) 的范围
    • 二等奖概率:30%. 即 [0.1 - 0.4) 的范围。注:为什么是从0.1开始?因为<0.1的话就是中了一等奖
    • 三等奖概率:40%  即 [0.4 - 0.8) 的范围
    • 剩余 20% 不中奖.  即 [0.8 - 1) 的范围
  • 生成随机数:使用 Math.random() 生成一个 [0, 1) 区间的随机数。

  • 根据随机数确定奖项:根据随机数值判断它落在哪个概率区间,决定抽中的奖项。要提高中奖难度,可以通过 缩小中奖概率区间 来减少中奖的机会  

复制代码
        class Lottery {
            constructor(prizes) {
                this.prizes = prizes; // 奖项的配置,例如 {1: 1, 2: x, 3: y}
                this.results = { 1: 0, 2: 0, 3: 0, none: 0 };
            }
            // 执行抽奖
            drawLottery() {
                const probabilities = [
                    { index: 1, chance: 0.1 },  // 一等奖 10%
                    { index: 2, chance: 0.3 },  // 二等奖 30%(累计到 40%)
                    { index: 3, chance: 0.4 }   // 三等奖 40%(累计到 80%)
                ];

                let random = Math.random();
                let cumulative = 0; // 累积概率
                for (let p of probabilities) {
                    cumulative += p.chance;  // 递增累计概率
                    if (random < cumulative && this.results[p.index] < this.prizes[p.index]) {
                        this.results[p.index]++; 
                        return `${p.index}等奖`;
                    }
                }
                this.results.none++; // 其他情况未中奖
                return '未中奖';
            }
            // 获取当前中奖情况
            getResults() {
                return this.results;
            }
        }
        // 创建一个抽奖实例,其中一等奖1个,二等奖3个,三等奖5个
        const lottery = new Lottery({1: 1, 2: 3, 3: 5});
        // 执行10次抽奖
        for (let i = 0; i < 10; i++) {
            console.log(lottery.drawLottery());
        }
        // 查看当前抽奖结果
        console.log(lottery.getResults());
复制代码

 

上面的代码在drawLottery中使用了递增累计方法来判断是否中奖,如果不使用该方法,代码虽然易理解,但很长,如下:

复制代码
  // 执行抽奖
  drawLottery() {
    // 生成 0 到 1 之间的随机数
    const random = Math.random();
 
    // 根据随机数的范围确定奖项
    if (random < 0.1 && this.results[1] < this.prizes[1]) {
      this.results[1]++; // 一等奖
      return '一等奖';
    } else if (random < 0.4 && this.results[2] < this.prizes[2]) {
      this.results[2]++; // 二等奖
      return '二等奖';
    } else if (random < 0.8 && this.results[3] < this.prizes[3]) {
      this.results[3]++; // 三等奖
      return '三等奖';
    } else {
      this.results.none++; // 未中奖
      return '未中奖';
    }
  }
View Code
复制代码

 

宫格抽奖核心算法:

  1. 计算停留在每个格子的百分比概率(非中奖项的要均分) 

    假设九宫格的网格编号为 [0, 1, 2, 3, 4, 5, 6, 7, 8],其中 2、5号网格为中奖网格,概率分别为1%、10%。

  2. 将中奖格子和未中奖格子分为两个数组
  3. 随机生成一个数,判断是否在中奖格子区间(递增累计概率判断法),如果在,返回对应的网格号;
  4. 从未中奖的数组中随机返回一个网格号
复制代码
function getWinningIndex() {
    const probabilities = [
        { index: 2, chance: 0.01 },  // 1% 概率
        { index: 5, chance: 0.10 }   // 10% 概率
    ];
    const otherIndexes = [0, 1, 3, 4, 6, 7, 8];
    let cumulative = 0; // 累计概率
    for (let p of probabilities) {
        cumulative += p.chance; // 累加当前概率
        if (randomNum < cumulative) {
            return p.index; // 落入此区间,返回对应格子
        }
    }
    // 如果前面没命中,均分的格子里随机选一个
    return otherIndexes[Math.floor(Math.random() * otherIndexes.length)];
}
复制代码

 

posted @ 2024-12-04 20:46  我是格鲁特  阅读(146)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2020-12-04 less或scss中波浪符的使用场景
点击右上角即可分享
微信分享提示