Choosing a level based on a precentage chance

Viewed 35

I have a JSON in the following format:

"fire": {
        "price": 25,
        "uniques": [
            23
        ],
        "levels": {
            "1": 30,
            "2": 50,
            "3": 10,
            "4": 6.5,
            "5": 2.5,
            "6": 0.9,
            "7": 0.1
        }
    }

The levels has my levels i need to choose, with the precentage chance as the values. (For example level 1 has a 30% chance)

I need to somehow choose a random level, while following those chances.

What I've tried: Smack my head against the wall

2 Answers

This approach generates a random value, and starts with a threshold of 1. It then iteratively subtracts the probability percentage of each level until hitting a level where the random value exceeds the threshold:

const probabilities = {
  "1": 30,
  "2": 50,
  "3": 10,
  "4": 6.5,
  "5": 2.5,
  "6": 0.9,
  "7": 0.1
};

const level = () => {
  const random = Math.random();
  let threshold = 1;
  
  for (let [level, percentage] of Object.entries(probabilities)) {
    threshold = threshold - (percentage / 100);
    
    if (random >= threshold) {
      return level;
    }
  }
}

console.log([...Array(20)].map(_ => level())); // 20 examples

If performance is a concern, you can pre-calculate the thresholds.

try this

const fire = {
  price: 25,
  uniques: [23],
  levels: {
    1: 30,
    2: 50,
    3: 10,
    4: 6.5,
    5: 2.5,
    6: 0.9,
    7: 0.1,
  },
};

var chances = Object.values(fire.levels).map(item => item / 100); // probabilities
var levels = Object.keys(fire.levels).map(Number); // values to return


function getRandom() {
  var num = Math.random(),
    s = 0,
    lastIndex = chances.length - 1;

  for (var i = 0; i < lastIndex; ++i) {
    s += chances[i];
    if (num < s) {
      return levels[i];
    }
  }

  return levels[lastIndex];
}

console.log(getRandom());
Related