You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Math.random()的爆炸骰函数在嵌套调用时异常,返回理论上不可能的最大值

基于Math.random()的爆炸骰函数在嵌套调用时异常,返回理论上不可能的最大值

嘿,我一眼就瞅到问题根儿在哪了——类型不匹配搞的鬼!

咱们拆解着看:

  • 你在multiDiceRoll里用diceString.split("d")处理骰子字符串,比如输入"1d8",拆分后得到的diceType是字符串"8",不是数字类型的8。
  • 然后你把这个字符串"8"直接传给了explosiveDiceRoll当maxRoll参数。
  • 但你的diceRoll函数返回的是数字类型的结果(比如8),在explosiveDiceRoll的循环判断roll === maxRoll里,数字8和字符串"8"用严格相等===比较会返回false——循环压根不会触发重滚逻辑!直接就把初始的8返回了,这就是为啥不该出现的8会冒出来。

至于你单独测试explosiveDiceRoll时没问题,是因为你直接传的是数字(比如8),类型一致,严格相等判断能正常工作。

解决方案

只需要把multiDiceRoll里的diceAmount和diceType转换成数字就行,用parseInt或者Number都可以:

function multiDiceRoll(diceString,advantage) {
    diceString = diceString.split("d");
    let diceAmount = parseInt(diceString[0], 10); // 转为数字
    let diceType = parseInt(diceString[1], 10); // 转为数字
    console.log(`${diceAmount}d${diceType}`);

    let results = [];
    for(let i = 0; i <= Math.min(2,Math.abs(advantage)); i++) {
        let result = 0;
        for(let d = 1; d <= diceAmount; d++) {
            let roll = explosiveDiceRoll(diceType);
            console.log(`${roll},${diceType} - SHOULD NOT EQUAL`);
            result += roll;
        }
        results.push(result);
    }
    console.log(results);
    if(advantage >= 0) return Math.max(...results);
    else return Math.min(...results);
}

另外,建议给explosiveDiceRoll也加个参数类型转换的保险,防止以后再不小心传字符串进去:

function explosiveDiceRoll(maxRoll) {
    maxRoll = parseInt(maxRoll, 10); // 确保是数字类型
    let roll = diceRoll(maxRoll);
    let sum = roll;
    while(roll === maxRoll) {
        roll = diceRoll(maxRoll);
        if(roll === 0) console.log("zero error");
        sum += roll
    }
    return sum;
}

改完之后,严格相等判断就能正常触发重滚逻辑,再也不会出现返回最大值的情况了。你再用之前的while循环测试,应该能和单独测试explosiveDiceRoll一样一直运行下去。

备注:内容来源于stack exchange,提问作者KaiMcKiernan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:48:06