Search code examples
javascriptnode.jsprobability-distribution

Wining prizes based off probabilities


I was curious on how wheel spinning based of chances algorithm would work so I wrote this code

I created an object with each prize and its probability

const chances = {
        "Apple" : 22.45,
        "Peaches" : 32.8,
        "Grapes" : 20,
        "Bananas" : 6.58,
        "Strawberry" : 18.17
    }

then I generate a random number and check if its within the prize's winning ranges

const random = Math.floor((Math.random() * 10000) + 1);
var rangeStart= 0;

    for (var key in chances){
        var rangeEnd= rangeStart+ chances[key];
        if (rangeStart*100 < random &&  random <= rangeEnd*100){
            console.log(rangeStart*100+" < "+random+" <= "+rangeEnd*100);
            console.log("You won a "+key)
            break;
        }
        rangeStart+= chances[key];
    }

you can check the code here

am I in the right path?


Solution

  • As already mentioned, instead of 10000 stick to percentages 100.
    To prove that your code works fine (if you're unsure about the used algorithm), in order to test it sample the results of many iterations. If the collected results are close to the expected original values - that's a good sign you're on the right track:

    Here's an example with 1,000,000 iterations. The precision seems pretty decent:

    const chances = {
      "Apple" : 22.45,
      "Peaches" : 32.8,
      "Grapes" : 20,
      "Bananas" : 6.58,
      "Strawberry" : 18.17
    };
    
    const results = {};
    
    const generate = () => {
      
      const random = Math.floor((Math.random() * 100) + 1);
      var rangeStart = 0;
    
      for (var key in chances){
        var rangeEnd = rangeStart+ chances[key];
        if (rangeStart < random &&  random <= rangeEnd){
          results[key] ??= 0;
          results[key] += 1;
          break;
        }
        rangeStart+= chances[key];
      }
    };
    
    // noprotect
    const samples = 1000000;
    for (let i=0; i<samples; i++) generate();
    
    Object.entries(results).forEach(([k, v]) => {
      console.log(`${k} ${(v / samples * 100).toFixed(2)}% (Expected: ${chances[k]}%)`); 
    });