Stack error pro
Stack error pro

Reputation: 45

How to choose between multiple options with different chances whithout making ugly code

I am asking this question for my JS code, but it's actually a problem that I'm having in every programming language.

Let's say I have 5 names for dogs in my simulation, I can hold them in an array and choose a random name for every dog like this

var NAMES = ["Scafy","Shimshon","WoofWoof","Mitzy","AnotherDogName"]//possible names for the dogs

dog.name = NAMES[Math.floor(Math.random()*NAMES.length)] // chooses a random name from for the dog

So this is simple. but my problem is when I want some of the sames to have higher or lower chance, with 5 names is not that difficult to do this:

give WoofWoof much higher chance of getting chosen than the other names by doing this ugly mess:

var NAMES = ["Scafy","Shimshon","WoofWoof","Mitzy","AnotherDogName"]//possible names for the dogs


function choose(){
   var random = Math.random()*100
   var name = NAMES[0]
   if (random>20)
      name = NAMES[1]
   if (random>30)
      name = NAMES[2]
   if (random>80)
      name = NAMES[3]
   if (random>90)
      name = NAMES[4]

   return name
}

This method works, but it's ugly, and becomes unbelievably complicated when there are a lot of options to choose from and many different chances.

I am sure than I am not the only one who had encounter this problem, and I feel like I'm missing a very elegant solution that hides just below my nose (I hope this sentence makes sense in english too)

This is a general question, I asked it in JS, but I have the same problem in any programming language.

My question is what's the most elegant way of doing it

Thank you

Upvotes: 0

Views: 643

Answers (1)

Jaime Argila
Jaime Argila

Reputation: 446

You wish to make your code look better and be more scalable? If so, this answer will help you.

//dog names and chances
var NAMES = [
    {
        name: "Scafy",
        chance: 0.2
    },
    {
        name: "Shimshon",
        chance: 0.1
    },
    {
        name: "WoofWoof",
        chance: 0.5
    },
    {
        name: "Mitzy",
        chance: 0.1
    },
    {
        name: "AnotherDogName",
        chance: 0.1
    }
]

//In chances dont add up to 1
var maxChance = 0;
for (let i = 0; i < NAMES.length; i++) {
    maxChance += NAMES[i].chance;
}



function choose() {
    //to make chance range fair.
    var random = Math.random() * maxChance

    var name;
    //keeps track of were one is in the chancing
    let randomTrack = 0;

    //chancing
    for (let i = 0; i < NAMES.length; i++) {
        randomTrack += NAMES[i].chance;
        if (random <= randomTrack) {
            name = NAMES[i].name;
            //stop when you dog got lucky
            break;
        }
    }

    return name;
}

Upvotes: 1

Related Questions