Pick Item From List At Random, Each Has Different Chance
Solution 1:
I'd solve it by having an array of objects with a chance to be the result, totalling 1.0
, then picking a random number between 0 and 1, and then iterating over the resources and check if adding it to a cumulative total includes your random number.
var resources = [
{ resource: false, chance: 0.2 },
{ resource: 'nitrogen', chance: 0.1 },
{ resource: 'silicon', chance: 0.2 },
{ resource: 'cobalt', chance: 0.45 },
{ resource: 'mangesium', chance: 0.05 }
];
functionget_result(resouceList) {
//get our random from 0 to 1var rnd = Math.random();
//initialise our cumulative percentagevar cumulativeChance = 0;
//iterate over our resourcesfor (var i = 0; i < resouceList.length; i++) {
//include current resource
cumulativeChance += resouceList[i].chance;
if (rnd < cumulativeChance)
return resouceList[i].resource;
}
returnfalse;
}
//testconsole.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
Solution 2:
I would set it up so that only the actual resources are in your array and "empty" happens if the random roll falls outside of those.
this.resources = [
{ type: 'nitrogen', chance: 10 },
{ type: 'silicon', chance: 20 },
{ type: 'cobalt', chance: 30 },
{ type: 'magnesium', chance: 10 }
];
this.assign_resource = function() {
var rnd = Math.random();
var acc = 0;
for (var i=0, r; r = this.resources[i]; i++) {
acc += r.chance / 100;
if (rnd < acc) return r.type;
}
// rnd wasn't less than acc, so no resource was foundreturn'empty';
}
Solution 3:
You can do something like this.
Creating an array with the same value multiple times gives it a higher chance of being selected.
var resources = [{
type: 'empty',
chance: 30
},
{
type: 'nitrogen',
chance: 10
},
{
type: 'silicon',
chance: 20
},
{
type: 'cobalt',
chance: 30
},
{
type: 'magnesium',
chance: 10
}
];
functionGetRandom(list) {
var array = [];
for (var i = 0; i < list.length; i++) {
var item = list[i];
var chance = item.chance / 10;
for (var j = 0; j < chance; j++) {
array.push(item.type);
}
}
var idx = Math.floor(Math.random() * array.length);
return array[idx];
}
console.log(GetRandom(resources))
.as-console-wrapper { max-height: 100%!important; top: 0; }
Solution 4:
This is how I'd implement the solution. Step 1: accumulate all the possible chances Step 2: pick a random value in proportion to total chance Step 3: loop through the resources to see in which part it random value falls under.
var resources = [
{ type: 'empty', chance: 30 },
{ type: 'nitrogen', chance: 10 },
{ type: 'silicon', chance: 20 },
{ type: 'cobalt', chance: 30 },
{ type: 'magnesium', chance: 10 }
];
functionsolution(resources) {
let chanceTotal = resources.reduce((acc, val) => { acc += val.chance ; return acc;}, 0);
let randomVal = parseInt(Math.random() * chanceTotal);
let chanceAcc = 0;
let ans;
resources.forEach(r => {
chanceAcc += r.chance;
if (chanceAcc > randomVal && !ans) {
ans = r;
}
});
return ans;
}
console.log(solution(resources));
Solution 5:
Here is another implementation.
var res = [
["empty", 3],
["nitrogen", 1],
["silicon", 2],
["cobalt", 3],
["magnesium", 1]
];
var flat = [];
var item;
for(var i = 0, l = res.length; i < l; i++) {
item = Array(res[i][1]+1).join(i+",");
item = item.substr(0, item.length-1);
flat.push(item);
}
flat = flat.join(",").split(",");
functionget_random_item() {
var ridx = Math.floor(Math.random() * (flat.length));
return res[flat[ridx]][0];
}
var pick;
for(var p = 0; p < 50; p++) {
pick = get_random_item();
console.log(p, pick);
}
Post a Comment for "Pick Item From List At Random, Each Has Different Chance"