Reputation:
I'm making a Discord.js bot and one of the functions of the bot is to return a random item from a Javascript array of facts when a user types "!fact". This question has been asked a lot by other users and I've used code from answers given to them but I've run into one problem: the bot gets "stuck" on one fact and doesn't go through the list randomly every time "!fact" is typed. This is an example of the code I have so far:
var facts = [ "Fact 1", "Fact 2", "Fact 3", "Fact 4" ]
var fact = Math.floor(Math.random() * facts.length);
And then, for the bot to send the message:
client.on('message', message => {
if (message.content === "!fact") {
message.channel.send(facts[fact]);
console.log('Message sent');
}
});
But this would only return something like Fact 1
over and over, no matter how many times "!fact" is typed. How can I make it change every time?
Upvotes: 1
Views: 861
Reputation: 129
Math.random() return a float value between 0 and 1, so multiply this number for an integer not necessary (almost never) return an integer number, that is actually what you need to iterate over an array.
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Math/random
The Math.random() function returns a floating-point, pseudo-random number in the range 0 to less than 1 (inclusive of 0, but not 1) with approximately uniform distribution over that range — which you can then scale to your desired range. The implementation selects the initial seed to the random number generation algorithm; it cannot be chosen or reset by the user.
To work around this you can typically use Math.round() or Math.floor.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
The Math.floor() function returns the largest integer less than or equal to a given number.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
The Math.round() function returns the value of a number rounded to the nearest integer.
Since you need to limit your range on your facts.length you can use Math.floor, to never get the length value since the index of arrays to start on 0, in other words, the index of the last fact is equal to (facts.length - 1).
client.on('message', message => {
if (message.content === "!fact") {
const factIndex = Math.floor(Math.random() * facts.length);
const fact = facts[factIndex]
message.channel.send(fact);
console.log('Message sent');
}
});
Upvotes: 2
Reputation: 12891
You're determining your random fact just once at startup using this line:
var fact = Math.floor(Math.random() * facts.length);
To get a random fact each time the if-condition evaluates to true you need to re-assign a new random integer to facts in there:
client.on('message', message => {
if (message.content === "!fact") {
fact = Math.floor(Math.random() * facts.length);
message.channel.send(facts[fact]);
console.log('Message sent');
}
});
Upvotes: 4