Home > Blockchain >  Wining prizes based off probabilities
Wining prizes based off probabilities

Time:12-03

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?

CodePudding user response:

It looks like you are on the right track. Your code is almost correct. However, there are a few issues that you need to fix.

First, you are generating a random number between 1 and 10000, but the probabilities in your chances object are percentages. This means that the total sum of all the probabilities is 100, not 10000. You need to generate a random number between 1 and 100 instead.

Second, in the loop you are multiplying rangeStart and rangeEnd by 100 before checking if the random number is within the range. This will make the comparison always false, because rangeStart and rangeEnd are percentages, not 100 times the actual percentage value. You need to remove the multiplication by 100 from the comparison.

Here is the updated code with these changes applied:

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

const random = Math.floor((Math.random() * 100)   1);
let rangeStart = 0;

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

I hope this helps.

CodePudding user response:

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]}%)`); 
});

  • Related