So, let's say I'm making something like a slots machine, to use the emojis I'd like to use I'd define them in an array.
var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]
Let's say I'd want emojis 1 - 4 to appear more than 5, and say decrease the probability of emoji5 being picked.
I could do something large like:
var arr = [
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4","emoji5",
]
var emoji = arr[Math.floor(Math.random() * arr.length)]
But that is not a very efficient idea, so is it possible to do the idea above without making a very large array?
What I'm aiming for basically is to have an array like
var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]
and it would output something where emojis 1 - 4 would appear way more often than emoji5, without a large array.
For the general case of weighted probabilities, one option would be to have an object whose keys are of cumulative probabilities. Say you wanted emoji5 to occur 4% of the time - then, the cumulative probabilities would be 24, 48, 72, 96, 100 (where the last interval of 96 to 100 indicates emoji5's low weight) . Then generate a random number between 1-100 and find the first key which is greater than the picked number:
const probs = {
24: "emoji",
48: "emoji2",
72: "emoji3",
96: "emoji4",
100: "emoji5"
};
const keys = Object.keys(probs).map(Number);
const generate = () => {
const rand = Math.floor(Math.random() * 100);
const key = keys.find(key => rand < key);
return probs[key];
};
for (let i = 0; i < 10; i++) {
console.log(generate());
}
Another option would be to associate a weight
number with each string, and give the emoji5
a low one, add up the weights, generate a random number between 0 and the total weight, and find the first match:
const weights = [
[4, 'emoji'],
[4, 'emoji2'],
[4, 'emoji3'],
[4, 'emoji4'],
[1, 'emoji5'],
];
const totalWeight = weights.reduce((a, [weight]) => a + weight, 0);
const weightObj = {};
let weightUsed = 0;
for (const item of weights) {
weightUsed += item[0];
weightObj[weightUsed] = item;
}
const keys = Object.keys(weightObj);
const generate = () => {
const rand = Math.floor(Math.random() * totalWeight);
const key = keys.find(key => rand < key);
return weightObj[key][1];
};
for (let i = 0; i < 10; i++) {
console.log(generate());
}
Try in this way
var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]
var emoji = arr[Math.floor(Math.random() * (Math.random() < 0.75 ? arr.length - 1 : arr.length))]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With