A little post about a little GameMaker script to randomly return one of the values while minding their "weights"
- in other words, a "biased" version of `choose`.

## The idea

First, we add up chances from each option.

Then we generate a random number between 0 (incl.) and that number (excl.).

Then, we starting subtracting chances from this number until it reaches 0 or lower, at which point we return the associated item.

If you had *a lot* of options, it would make sense to perform a binary search instead.

## The code

For GameMaker Studio 2.3+:

function choose_weighted() { var n = 0; for (var i = 1; i < argument_count; i += 2) { if (argument[i] <= 0) continue; n += argument[i]; } n = random(n); for (var i = 1; i < argument_count; i += 2) { if (argument[i] <= 0) continue; n -= argument[i]; if (n < 0) return argument[i - 1]; } return argument[0]; }

For older versions:

var n = 0; for (var i = 1; i < argument_count; i += 2) { if (argument[i] <= 0) continue; n += argument[i]; } n = random(n); for (var i = 1; i < argument_count; i += 2) { if (argument[i] <= 0) continue; n -= argument[i]; if (n < 0) return argument[i - 1]; } return argument[0];

If you are sure that you'll never pass in negative chances,
you can remove the `if (argument[i] <= 0) continue;` lines.

The last `return` statement will never execute (as `random(n)` cannot exceed `n`),
but it is good practice to return on all paths in your functions.

And that's all!

Thanks for this excellent function!

Someone recommended it here in this thread: https://forum.yoyogames.com/index.php?threads/ratio-based-chance.95114/

and it works perfectly.

I don’t fully understand how this works. Could you post an example of what you’d put into this when using the function (IE, the argument) and what your output/result would be?

An example of use is demonstrated on the first image in the post – choose_weighted(“A”, 3, “B”, 1) would yield “A” 3/4 of time and “B” 1/4 of time.