Reputation: 524
Okay, so let's say I store some of my data like this,
var thisList = {
"items":[
{"name":"Item1", "image":"/img/item1", "chance":0.25},
{"name":"Item2", "image":"/img/item2", "chance":0.25},
{"name":"Item3", "image":"/img/item3", "chance":0.50}
]
}
Now I'd like to create a function that randomly picks a item out of this list with the chances being 25% of getting [0], another 25% of getting [1] and a 50% chance of getting [2]!
Is this possible? If so, how'd I do this?
Kind regards!
Upvotes: 4
Views: 841
Reputation: 340045
You need to look at the cumulative sum of all odds seen so far in the array. With the sample data you've given those values would be 0.25, 0.5, 1.0
Then given a random number in the range [0, 1), just pick the first entry where the cumulative value is less than that number.
Here's an example implementation:
const pickRandom = (() => {
let target = Math.random(), total = 0.0;
return (e, i, a) => {
total += e.chance;
return target < total;
}
});
let picked = thisList.items.find(pickRandom());
The pickRandom
function needs to be called exactly once per round, and returns a function that encapsulates the state necessary to accumulate the chances seen so far, and the random number that is to be used.
That function then becomes the predicate used by Array.prototype.find
to extract the appropriate random item.
Upvotes: 0
Reputation: 1125
You can actually play it like this, tou generate a number between 0 and 100 and then you cycle on each element and sum the chance to check if it is between the value or not:
var thisList = {
"items":[
{"name":"Item1", "image":"/img/item1", "chance":0.25},
{"name":"Item2", "image":"/img/item2", "chance":0.25},
{"name":"Item3", "image":"/img/item3", "chance":0.50}
]
};
function getRandom(){
var rnd = Math.floor(Math.random() * 100);
console.log("The number is: " + rnd);
var counter = 0;
for(i=0;i<thisList.items.length;i++)
{
counter += thisList.items[i].chance * 100;
if(counter > rnd){
console.log(thisList.items[i]);
break;
}
}
}
getRandom();
EDIT:
If you want to control even with a variant chance you can do this:
var thisList = {
"items":[
{"name":"Item1", "image":"/img/item1", "chance":0.25},
{"name":"Item2", "image":"/img/item2", "chance":0.25},
{"name":"Item3", "image":"/img/item3", "chance":0.50}
]
};
function getRandom(){
var sum = 0;
for(i=0;i<thisList.items.length;i++)
{
sum += thisList.items[i].chance;
}
var rnd = Math.floor(Math.random() * (sum * 100));
console.log("The number is: " + rnd);
var counter = 0;
for(i=0;i<thisList.items.length;i++)
{
counter += thisList.items[i].chance * 100;
if(counter > rnd){
console.log(thisList.items[i]);
break;
}
}
}
getRandom();
Upvotes: 4