1. Hey! Guest! The 32nd GMC Jam will take place between Feb 22nd, 12:00 UTC (Friday noon) and Feb 25th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

More complex choice with percentages

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

  1. Shadowrend

    Shadowrend Member

    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. TheSly

    TheSly Member

    Joined:
    Jan 16, 2017
    Posts:
    672
    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. Shadowrend

    Shadowrend Member

    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. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,049
    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. Shadowrend

    Shadowrend Member

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

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice