Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Return random based off percentage

I've been trying to figure out a way to accomplish this, but I'm running into a wall and I figured I would ask here.

Here is an example:

Let's say I have two objects, food and water, and they have different 'chance' values. One has a 20% chance, one a 40% chance. How would I be able to mathematically add to their total, given that percentage?

var food = {
    name:'food',
    total:0,
    chance:0.2
};
var water = {
    name:'water',
    total:0,
    chance:0.4
};

This is what I have so far, but this isn't really percentage based. Looking for ways to improve it.

function test() {
    var x = parseFloat(Math.random().toFixed(1));

    if(x == food.chance) {
        food.total += 1;
    }
    if(x == water.chance) {
        water.total += 1;
    }
}

Any help or guidance is appreciated.

Thanks!

2 Answers

Hi, Shawn. Since you're working with chance, you'll probably want to deal with ranges. As you know, Math.random() returns a value between 0 (inclusive) and 1 (non-inclusive), so for your conditional statement, you would probably want to use the <= comparison operator, that way there is a chance that your if statement will result as true causing the conditional statement to run. If you're doing a game-like application, I'd also recommend re-rolling your x variable for the second item (water) so you have a random chance at both, like so:

function test() {
    var x = parseFloat(Math.random().toFixed(1));
    if(x <= food.chance) {
        food.total += 1;
    }

    x = parseFloat(Math.random().toFixed(1));
    if(x <= water.chance) {
        water.total += 1;
    }
}

Of course, you could always create an extra function to call for your rolling, since you probably don't want repeated code all over the place. Hope that helps! :)

I think you made a mistake in your line if (x == water.chance). If you have that, it will only be true if the random number is exactly .4, which is really a probability of .1, instead of the intended probability of .4.

EDIT: Nevermind I see you fixed it while I typed my response. :)

Thank you both for your comments, I appreciate the help.

I understand what both of you are suggesting. I do have a follow up question though. Would something like this be able to deal with two items that have the same percentage chance. Like say there are 5 possible items, with the values of 20%, 20%, 10%, 10%, and 40%.

That is really what I'm trying to solve. I should have been more specific in my example.

Again, I appreciate the help :)

It depends on how you want to be able to handle your logic. Assuming a item-drop scenario in a game from killing a monster, you'd need to decide if it's possible to have all items drop at the same time, or is the maximum number of items that can drop, say, one? In that case, you'd have to put a counter in place to ensure that the number of items dropped doesn't exceed the max allowed number. As long as you are re-rolling your x value before each if statement, then you could have 100 items with the same drop chance.

Thanks again Ryan, I believe I got it now.

You could do something like this:

function test() {
    var x = parseFloat(Math.random());

    if(x >= 0 && x <= food.chance) {
        food.total += 1;
    }
    if(x > food.chance && x <= (food.chance + water.chance)) {
        water.total += 1;
    }
}

This way, when the random number is between 0 and .2 it will add to the food total. And when the random number is between .2 and .6 it will add to the water total. If it is above .6 it will do nothing.