# More complex choice with percentages

Discussion in 'Programming' started by Shadowrend, Feb 11, 2019.

1. ### ShadowrendMember

Joined:
Jun 20, 2016
Posts:
20
Hello,

Been trying to make a more complex "choice" function, which basically has each argument have an argument for the % of it being chosen, so you could instead of using choose(A,B) where each has 50% chance, you could do choose_percent(A,30,B,50) and then A would have 30% chance, and B 50%, and the remaining 20% would return 0 or false.

I have no good idea about doing this, maybe someone could help me. The idea I had in my mind was comparing A to B to C etc, but that seems like a very bad way of doing this.

Thanks

2. ### TheSlyMember

Joined:
Jan 16, 2017
Posts:
947
Not saying this is a good solution, but you can do this, depending on your needs. 16 choices are the max.
Code:
```choose(A, A, A, B, B, B, B, B, 0, 0)
```
That would be 30% A, 50% B and 20% 0

3. ### ShadowrendMember

Joined:
Jun 20, 2016
Posts:
20
I am hoping to avoid using "choose()" just for the limitations in the control of the percentages. What if I need A to be 43.2% and B 17.05% Either way, googling a bit, I found an old reddit post where someone called "xLeonhart" posted this code, it seems to work, but if someone knows a better way of doing it, great!
Code:
```///random_chance((ret,chance)[1-n],[def_ret])

var _def=noone;

if(argument_count%2){
_def=argument[argument_count-1];
}

var _i;
var _rand = irandom(9999)+1;
var _curchance = 0;

for(_i=1; _i<argument_count; _i+=2){
_curchance+=argument[_i]*100;
if(_rand<_curchance) return argument[_i-1];
}

return _def;```
Another one was from a user called ZeCatox who posted
Code:
```// a[n,0] = value; a[n,1] = chance;
a[0,0] = 1; a[0,1] = 10;
a[1,0] = 2; a[1,1] = 20;
a[2,0] = 5; a[2,1] = 5;

var sum = 0;
for(var i=0; i<array_height_2d(a); i++) sum+=a[i,1];

var r = random(sum);

i = 0;
while(r >= a[i,1])
{
r -= a[i,1];
i++;
}
your_value = a[i,0];
```
But I'm not liking that "while" as far as optimiztions go, since I'm running this script several thousand times at game start.

4. ### TheouAegisMember

Joined:
Jul 3, 2016
Posts:
6,627
That while and the for are doing the same thing: loop through all items in the probability. While loops aren't any worse than for loops; they do the exact same things essentially. What's more important is what each code actually does as a whole, not whether it uses a for or while loop. (The only "good" loop is repeat).

Both functions sum up all the probabilities and then loop through them until they find a hit. The biggest difference from what I see is the first code has the probability that nothing will be generated (if _rand is 9999 and the sum of all arguments is 3000, then nothing will be spawned. It also has the probability that some items will never we generated while the others will (if _rand is 9999 and the sum of all probabilities times 100 prior to the last one is over 9999, then one of those earlier ones will always get generated). The second code on the other hand has a guaranteed hit on any one of the arguments.

5. ### ShadowrendMember

Joined:
Jun 20, 2016
Posts:
20
Oh ok. I remember "while" being slow/buggy in GM8, at least in my experience. 