Skip to content Skip to sidebar Skip to footer

Pick Item From List At Random, Each Has Different Chance

I wanted to write a simple function that allows to roll random item from list, i did it with this code: this.resources = [false, 'nitrogen', 'silicon', 'cobalt', 'magnesium']; thi

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"