【问题标题】:Dice roll. DND, add numbers from an array together掷骰子。 DND,将数组中的数字相加
【发布时间】:2022-07-23 04:13:31
【问题描述】:

所以我为龙与地下城创建了一个基本的掷骰子 dicord 机器人。

到目前为止,我的代码可以用来掷任何类型的骰子,(例如“roll xdy”“roll 1d20”、“roll 100d100”)

当有人发送匹配的消息时,它会输出结果骰子。

我的问题是我想将这些数字加在一起并显示结果总数,但我不确定如何到达那里。

// Run dotenv
require('dotenv').config();

const { any } = require('async');
const Discord = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });


client.on('messageCreate', msg => {
        z = msg.content;
        matches = z.match(/\d+/g);
        x = matches[0];
        y = matches[1];

    if (msg.content === 'ping') {
        msg.reply('pong');
    }
    if (msg.content == 'roll ' + x + 'd' + y) {
        
        function rollDie(sides) {
            if (!sides) sides = 6;
            return 1 + Math.floor(Math.random() * sides);
        }

        function rollDice(number, sides) {
            var total = [];
            var number = x;
            var sides = y;
            while (number-- > 0) total.push(rollDie(sides));
            return total;
        }
        msg.reply("result: " + rollDice());
        console.log(rollDice())
    }
});

client.login(process.env.DISCORD_TOKEN);

【问题讨论】:

    标签: javascript discord bots dice


    【解决方案1】:

    似乎您在声明变量时没有使用 letvarzmatchesxy)。没有理由再使用var。你有 rollDice 函数的参数,但只是从你创建的变量中提取而不使用参数,所以我修改了它。我使用reduce 方法对数组求和。我将一些变量名称更改为更具描述性(例如 zmsgContent)并在更多可用的地方使用它们。

    在您的rollDie 函数中,您给出的默认骰子面数为 6,但由于 if 语句包装了它,调用该函数的唯一方法是专门选择一个面数。所以我修改了这个,如果他们只想掷 3 个 6 面骰子,他们可以键入“掷 3”。在报告掷骰子时,我使用了join 方法,因此它们将以逗号和空格分隔的列表而不是数组的形式显示。


    我在看到您的编辑后修改了这个解决方案。 msgContent 现在在顶部创建了一个我创建的新正则表达式,它足够强大,可以摆脱 toLowerCase 和 trim 方法输入擦洗以及代码中以前必需的其他字符串检查。 msg 将通过 regular expression test method 如果msg 是“roll #”或“roll #d#”(其中“#”是除 0 之外的任何数字长度的任何数字)。正则表达式将自动忽略字符大小写和字符串末尾的任何空格。我将rollDie 函数转换为更简洁的箭头函数并将其放在rollDice 函数范围内,因为这是唯一需要调用它的地方。您不需要写if (!sides) sides = 6;,因为您可以只使用表达式(sides || 6),因为sides 只使用一次,如果是falsy,该表达式将只计算为6。我也停止将diceResults 声明为一个空白数组,因为它可以在以后保存rollDice() 的输出时定义。

    require('dotenv').config();
    const { any } = require("async");
    const Discord = require("discord.js");
    const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });
    
    client.on("messageCreate", (msg) => {
      const msgContent = msg.content,
            msgRegEx = /\s*roll\s[1-9]\d*(d[1-9]\d*)?\s*/i;
    
      if (msgRegEx.test(msgContent) {
        let matches = msgContent.match(/\d+/g),
            numDice = matches[0],
            numSides = matches[1],
            diceResults;
    
        function rollDice(number, sides) {
          const rollDie = sides => Math.floor(Math.random() * (sides || 6)) + 1;
    
          let diceArray = [];
    
          while (number-- > 0) diceArray.push(rollDie(sides));
    
          return diceArray;
        }
    
        function calcDiceTotal(diceArray) {
          return diceArray.reduce(
            (previousValue, currentValue) => previousValue + currentValue,
            0
          );
        }
    
        diceResults = rollDice(numDice, numSides);
    
        msg.reply(
          "ROLLING... " + diceResults.join(", ") +
          " || TOTAL: " + calcDiceTotal(diceResults)
        );
      }
    });
    
    client.login(process.env.DISCORD_TOKEN);
    

    输出应如下所示:"ROLLING... 3, 1, 6, 3, 5 || TOTAL: 18"

    【讨论】:

    • 感谢您,我能够获取您提供的代码并在此过程中学到了一些东西。我做了一些更改,以阻止机器人在每次有人发送除“roll”以外的消息时中断,但由于您的修复,我设法让这一切正常工作。
    • 很高兴能提供帮助。我打算编辑并添加更多潜在的输入错误条件以防止其中断,但我认为这远远超出了问题的范围。很高兴你能弄明白。
    【解决方案2】:

    应该这样做。

    Reduce 将回调函数应用于给定数组的每个元素,因此您可以使用它来将数组的所有值相加并报告。

    将数组“totalArr”传递给此函数应该会为您提供数组中所有数字的总和

    Javascript

    const rollTotal = function (totalArr) {
    const startingRoll = 0;
    const subTotal = totalArr.reduce(
    (previousValue, currentValue) => 
     previousValue + currentValue,
    startingRoll
    );
    return subTotal;
    };
    

    测试

    console.log(rollTotal([1, 2, 3]));
    

    输出 = 6

    【讨论】:

      【解决方案3】:

      这是按预期工作的最终机器人代码,使用了上面的修复程序并对其进行了调整,因此当有人键入任何其他消息时机器人不会中断。

      看起来效果不错!

      require('dotenv').config();
      const { any } = require("async");
      const Discord = require("discord.js");
      const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });
      
      client.on("messageCreate", (msg) => {
      
        if (msg.content.startsWith('roll ')) {
          let msgContent = msg.content.trim().toLowerCase(),
              matches = msgContent.match(/\d+/g),
              numDice = matches[0],
              numSides = matches[1],
              diceResults = [];
      
          if (
            msgContent === "roll " + numDice ||
            msgContent === "roll " + numDice + "d" + numSides
          ) {
            function rollDie(sides) {
              if (!sides) sides = 6;
      
              return 1 + Math.floor(Math.random() * sides);
            }
      
            function rollDice(number, sides) {
              let diceArray = [];
      
              while (number-- > 0) diceArray.push(rollDie(sides));
      
              return diceArray;
            }
      
            function calcDiceTotal(diceArray) {
              return diceArray.reduce(
                (previousValue, currentValue) => previousValue + currentValue,
                0
              );
            }
      
            diceResults = rollDice(numDice, numSides);
      
            msg.reply(
              "ROLLING... " + diceResults.join(", ") +
              " || TOTAL: " + calcDiceTotal(diceResults)
            );
          }
        }
      });
      
      client.login(process.env.DISCORD_TOKEN);
      

      【讨论】:

      • 干得好。我看到的 1 个问题是 trim() 和 toLowerCase() 函数执行的输入清理现在用处有限,因为您在调用这些方法之前检查 if 语句中的 msg 内容。我已经为您修改了我的解决方案并添加了一个强大的正则表达式,它将以更好的方式检查输入,取消所有其他需要的输入清理和测试。我希望你能检查出来。
      猜你喜欢
      • 2017-02-23
      • 1970-01-01
      • 2021-03-12
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      相关资源
      最近更新 更多