1. OCAU Merchandise now available! Check out our 20th Anniversary Mugs, Classic Logo Shirts and much more! Discussion here.
    Dismiss Notice

Discord bot help - random result from array (.js)

Discussion in 'Programming & Software Development' started by NanoDuke, Jun 25, 2020.

  1. NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Hi OCAU, I have a truth or dare bot that a friend has written for me, but we're both beginners to javascript.
    This is the current code, but it's not random, and only goes down the list every time someone asks one of the prompts.
    Code:
    var truth = 1;
    var out = true;
    client.on('message', message => {
    if (message.content === '-truth') {
            truth ++;
            if (truth === 1) {message.channel.send('Have you ever thrown up on an airplane or on a boat?');
    } else if (truth === 2) {message.channel.send('Who was the worst friend you had and why?'); 
    You can see the issue, where it's very tedious to add new prompts in. And every time we have to restart the bot, it just repeats the same order, unless we manually adjust var truth = # to jump down the list somewhere.

    So I've found this example, but it's a full html/css/js combo, and I can't quite follow it.
    https://code.sololearn.com/W5Cjt5FiunQG/#js
    I know the answer is within, but I don't know how to merge what I have and what I want.

    I believe this is the important bit to pull a random answer from an array.
    Code:
    Math.floor(Math.random() * (max - min + 1) ) + min;
    This isn't homework. I can invite anyone to my Discord if they want to see proof ;)
     
  2. RnR

    RnR Member

    Joined:
    Oct 9, 2002
    Messages:
    15,184
    Location:
    Brisbane
    Hmm... why not shuffle the array of answers randomly at the start, and then your truth variable can just serve as the index to the array?

    Something like... (completely untested)
    Code:
    var questions = [
        {
            order: Math.random(),
            question: "blah whatever"
        },
        {next question}
    ];
    
    // shuffle entries
    questions.sort(function(a,b){return a.order-b.order;})
    And then do something like;

    Code:
    {message.channel.send(questions[truth].question);
    Although you might wanna start truth at zero as array indexing in js starts from zero.
     
    Last edited: Jun 25, 2020
    NanoDuke likes this.
  3. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Thanks for that. I understand exactly 0% of it, but I'll work on it.
    I wasn't sure about starting at zero or 1. In our code, we we already up to 40ish as a starting point. That's how often the bot was causing us issues haha
     
  4. RnR

    RnR Member

    Joined:
    Oct 9, 2002
    Messages:
    15,184
    Location:
    Brisbane
    Something like this;

    Code:
    var truth = 0;
    var out = true;
    var strings = [
       'Have you ever thrown up on an airplane or on a boat?',
       'Who was the worst friend you had and why?'
    ];
    
    var questions = [];
    
    // build an object for each question
    strings.forEach(function(s) {
       questions.push({
           order: Math.random(),
           question: s
       });
    });
    
    // shuffle entries
    questions.sort(function(a,b){return a.order-b.order;});
    
    client.on('message', message => {
        if (message.content === '-truth') {
            truth++;
            message.channel.send(questions[truth].question);
        }
    });
         
    Ok after a few edits, I hope the above makes sense :D
     
    Last edited: Jun 25, 2020
    NanoDuke likes this.
  5. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Hmm. So I managed to splice it in to our existing code, but I think there's a loop somewhere, because when I asked the bot, it just started spitting out reply after reply:

    Have you ever thrown up on an airplane or on a boat?
    [3:34 PM]
    test 4
    [3:34 PM]
    test 4
    [3:34 PM]
    test 5
    [3:34 PM]
    test 5
    [3:35 PM]
    test 4
    [3:35 PM]
    test 5
    [3:35 PM]
    test 2
    [3:35 PM]
    test 5
    [3:35 PM]
    Who was the worst friend you had and why?
    [3:35 PM]
    test 3

    At least the random works :thumbup:

    What's the purpose of question: s?

    Also this line has nothing in the square brackets? var questions = [];
    Oh, I think .push is populating this array, am I right?

    I'm trying to learn this, line by line.
     
    Last edited: Jun 28, 2020
  6. RnR

    RnR Member

    Joined:
    Oct 9, 2002
    Messages:
    15,184
    Location:
    Brisbane
    Yup. 'questions' just stores an order with a question, so all the questions can be shuffled correctly... ie sorted by the order field. I did it this way so the strings array could be as simple as possible. You will probably have many entries in there eventually and saving on typing could help.

    Not sure on the loop, you will have to post more code :)
     
    Last edited: Jun 28, 2020
  7. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Ah I think I see what I did wrong.
    We have different sections for each prompt of -truth -wyr and -dare. And it starts with what I posted in OP, but then the next section starts with an else if
    Code:
    //WYR
    //     } else if (wyr === 2) {message.channel.send('');
    else if (message.content === '-wyr') {
            wyr ++;
            if (wyr === 1) {message.channel.send('Would you rather have telekinesis or telepathy?');
    So by dropping in your code, I've ended up with two client.on('message', message => { lines. While I don't fully understand the repurcussions, I can see that having two of them is a bad thing.
    Back to testing.
     
  8. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Cool. I think I got it (I used -next to not interfere with existing -truth commands.
    Code:
    //NEXT
    else if (message.content === '-next') {
        next++;
        
    // build an object for each question
    strings.forEach(function(s) {
       questions.push({
           order: Math.random(),
           question: s
       });
    });
    
    // shuffle entries
    questions.sort(function(a,b){return a.order-b.order;});
          
            message.channel.send(questions[next].question);
        }
     
    RnR likes this.
  9. RnR

    RnR Member

    Joined:
    Oct 9, 2002
    Messages:
    15,184
    Location:
    Brisbane
    The questions array and the shuffle should be done once only. Untill you reset the state of the game anyways.
     
  10. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Ah so by rejigging the sequence, it's now redoing the array every time -next is called...
    I'll go back and see what was wrong between where I got the loop and to now.
     
    RnR likes this.
  11. OP
    OP
    NanoDuke

    NanoDuke Member

    Joined:
    Feb 4, 2007
    Messages:
    7,591
    Location:
    Sydney
    Next noob question here. What happens once it gets to the bottom of the array? Does it still count down the list until it gets to var truth = n, where n = number of prompts in the array?

    I know that } else if (truths === n) {truth = 1; can reset the count back to = 0, but I'm not sure if it's needed since we're using an array.
     
  12. RnR

    RnR Member

    Joined:
    Oct 9, 2002
    Messages:
    15,184
    Location:
    Brisbane
    Yeah you need something to reset the array index back to zero, otherwise you will just get a value of undefined rather than a proper string.
     

Share This Page

Advertisement: