概率配置表 (fragmentProbabilities)
该对象定义了碎片抽奖系统的核心概率规则。键表示当前已拥有的碎片数量,值表示获得下一片新碎片的概率(百分比)。
这是基于官方公示数据构建的逐片递减概率模型。
const fragmentProbabilities = {
1: 100,
2: 96,
3: 92,
25: 0.29
};
累积概率函数 (cumulativeProbability)
该函数计算在第n抽时已经获得第25片碎片的累积概率。采用分段函数设计,模拟真实抽奖系统的渐进式保底机制:
- 阶段1 (25-199抽):线性缓慢增长,模拟早期低概率
- 阶段2 (200-250抽):指数增长,进入软保底区间
- 阶段3 (251-300抽):强保底阶段,快速收敛到100%
- 硬保底 (301抽及以上):必定获得全部碎片
function cumulativeProbability(n) {
if (n < 25) return 0;
if (n <= 199) {
return 0.00005 * (n - 24);
} else if (n <= 250) {
const k =
-Math.log(1 - (0.985 -
0.00875) / 0.97625) /
51;
return 0.00875 + 0.97625 * (1 - Math.exp(-k * (n - 199)));
} else if (n <= 300) {
const λ =
-Math.log(1 - (1 - 0.985) / 0.015) / 50;
return 0.985 + 0.015 * (1 - Math.exp(-λ * (n - 250)));
}
return 1;
}
单次抽奖核心函数 (performSingleDraw)
这是抽奖系统的核心执行函数,整合了基础概率、保底机制和特殊规则。函数执行流程:
- 更新抽奖计数器
- 检查是否已集齐所有碎片
- 确定目标碎片编号(顺序获得机制)
- 根据目标碎片应用不同的概率规则
- 执行概率判定并更新状态
- 处理特殊事件(如获得终极碎片)
function performSingleDraw() {
state.drawCount++;
if
(state.ownedFragments.length >= 25) {
addLog(`第${state.drawCount}抽:已集齐所有碎片,无需再抽`);
return;
}
const target =
nextMissing();
let baseProbability;
if (target >= 23) {
baseProbability = lateFragmentP(state.drawCount);
} else {
baseProbability = fragmentProbabilities[target] /
100;
}
if (state.drawCount >=
300 && state.ownedFragments.length < 25) {
baseProbability = 1;
}
const got = Math.random()
< baseProbability;
if (got) {
state.ownedFragments.push(target);
if (target ===
25) {
addLog(`第${state.drawCount}抽:获得终极碎片 #25!`);
updateFragmentsGrid();
updateStats();
setTimeout(() => {
epicPopup.style.display =
'flex';
}, 500);
return;
}
addLog(`第${state.drawCount}抽:获得碎片 #${target}`);
updateFragmentsGrid();
} else {
addLog(`第${state.drawCount}抽:未获得新碎片`);
}
updateStats();
}
系统设计特点
概率系统:结合官方概率数据和渐进式保底机制,模拟真实抽奖体验。
抽奖逻辑:采用顺序获得机制确保碎片按编号顺序获得,无跳号现象。
保底机制:包含Soft Pity机制(后期概率线性提升)和硬保底兜底(300抽强制获得)。
特殊处理:25号碎片检测和批量抽奖优化(集齐后自动停止)。
这套系统通过数学建模和概率计算,准确地模拟了真实抽奖系统的行为,为学习交流提供了可靠的技术演示。