So its basically a giveaway system where it chooses random name from my array of objects.
High Chance
= Higher chance of winning / getting picked
[
{name: "Prank", Chance: 23},
{name: "Em", Chance: 53},
{name: "John", Chance: 12}
]
CodePudding user response:
Clean, mathematical approach would be to generate a random number within the range of the data, using the total Chance
calculated from reducing the array.
Then, representing your array as an accumulation of the chances, you can use a total
variable to keep track of your starting point as you locate where the random value falls in your data.
const data = [
{name: "Prank", Chance: 23},
{name: "Em", Chance: 53},
{name: "John", Chance: 12}
];
function genWinner() {
let total = 0;
const rand = Math.floor(Math.random() * data.reduce((a,b)=>a b.Chance,0));
for (const item of data)
if (rand >= total && rand < (total = item.Chance)) return item;
}
console.log(genWinner());
CodePudding user response:
You could use Math.random
multiply the sum of chance
.
const array = [{
name: "Prank",
Chance: 23
},
{
name: "Em",
Chance: 53
},
{
name: "John",
Chance: 12
}
]
let passedvalue;
function makerandom() {
const sumchance = array.reduce((sum, b) => sum b.Chance, 0)
//add 0.01 because Math.random not include the last num
const ran = Math.random() * (sumchance / 100) 0.01;
console.log(ran)
let isfound = false
array.forEach((i, index) => {
if (!isfound) {
const partsum = array.slice(0, index 1).reduce((sum, b) => sum b.Chance, 0)
if (ran < partsum / 100) {
console.log("found it")
passedvalue = i
isfound = true;
}
}
})
}
makerandom()
console.log(passedvalue)
CodePudding user response:
During the random drawing, each chance is divided by the max chance. For example, if chance is 10 and the max is 100, then this player will have 0.1 or 10% of the max. This means they will have to rely more on getting lucky on the random number. The random number can be 0-1,the max weight is 1, and all weights less than max will have a range from 0 to less than 1, scaled relative to the maximum.
var contestants = [
{name: "Prank", Chance: 23},
{name: "Em", Chance: 53},
{name: "John", Chance: 12}
];
//Get the player with greatest chance of winning
var maxChance = contestants.sort((a,b) => b.Chance - a.Chance)[0].Chance;
//random drawing adds score property that we can use to sort the list
var round = contestants.map(a => {
a.score = a.Chance > 0 ? Math.random() * (a.Chance/maxChance) : 0;
return a;
}).sort((a,b) => b.score - a.score)
//winner of the round is the first result
var winner = round[0].name;
document.querySelector("div").innerText = JSON.stringify({winner,round},null,2);
<div></div>
CodePudding user response:
let entrants = [
{name: "Prank", Chance: 23},
{name: "Em", Chance: 53},
{name: "John", Chance: 12}
], weighted = [], roll, winner;
entrants.forEach(e => {
for(let i = 0; i < e.Chance; i){
weighted.push(e.name);
}
});
roll = Math.floor(Math.random() * (weighted.length 1));
winner = weighted[roll];
console.log(winner);
//Example running 100 times to check averages.
let example = [winner], prankCount = 0, emCount = 0, johnCount = 0;
for(let i = 0; i < 99; i){
roll = Math.floor(Math.random() * (weighted.length 1));
example.push(weighted[roll]);
}
example.forEach(e => {
if(e === "Prank") prankCount;
else if(e === "Em") emCount;
else johnCount;
});
console.log(prankCount "%", emCount "%", johnCount "%");