[Script] Weighted Select Random
Posted: Fri Jan 29, 2016 6:34 pm
EDIT: I'm dumb and didn't realize that BIS_fnc_selectRandomWeighted is a thing. Still, my script has several advantages, including the ability to set weights greater than 1 and (IMO) a better format for the input array. Consider this a bit of a tutorial/launching point for your own scripts in any case.
=================
This is a little script that I've found is quite useful in creating dynamic spawn scripts. Basically, it's a weighted version of BIS_fnc_selectRandom. Instead of selecting a random item from a list of items, it selects a random item from an adhoc map of weights to items, with higher-weighted items being more likely to be selected.
Example usage:
This is functionally the same as calling:
So, how is this useful? Let's say you want to randomly spawn a group of infantry. You want the groups you spawn to mostly be riflemen, but you don't want to hardcode your group composition. You could do something like this:
On average, this would spawn 6-man groups composed of 4 riflemen, 1 autorifleman, 1 AT rifleman, with occasional groups spawning with a medic or a sharpshooter. This same concept can be extended to group spawns as well; for example, you could have a spawn script that mostly spawns infantry teams but occasionally spawns MRAPs or armor instead. The reinforcements script for Upward Mobility and the dynamic spawn script for (the as-of-yet unplayed) Convoy are both written using this approach.
The script:
Pastebin
=================
This is a little script that I've found is quite useful in creating dynamic spawn scripts. Basically, it's a weighted version of BIS_fnc_selectRandom. Instead of selecting a random item from a list of items, it selects a random item from an adhoc map of weights to items, with higher-weighted items being more likely to be selected.
Example usage:
Code: Select all
weightedSelectRandom = compileFinal preprocessFileLineNumbers "weightedSelectRandom.sqf";
[[1,item0],[1,item1],[2,item2]] call weightedSelectRandom;
Code: Select all
[item0,item1,item2,item2] call BIS_fnc_selectRandom;
Code: Select all
_group = createGroup west;
for "_i" from 1 to 6 do {
_class = [[4,"B_Soldier_G"],[1,"B_soldier_AR_F"],[1,"B_soldier_LAT_F"],[.2,"B_medic_F"],[.1,"B_Sharpshooter_F"]] call weightedSelectRandom;
_group createUnit [_class,getMarkerPos "spawn",_group,[],0,"FORM"];
};
The script:
Pastebin
Code: Select all
/*
* Randomly select an item from a weighted array. Array should be in the following format:
* [[weight0,item0],[weight1,item1]...]. Items with a higher weight are more likely to be
* chosen; for the array [[1,item0],[2,item1]], there is a 1/3 chance of choosing item0
* and a 2/3 chance of choosing item1.
*
* Example usage: [[1,item0],[1,item1],[2,item2]] call weightedSelectRandom;
*/
_sum = 0;
{ _sum = _sum + (_x select 0); } forEach _this;
_roll = random _sum;
_sum = 0;
{
_sum = _sum + (_x select 0);
if (_roll < _sum) exitWith {_x select 1};
} forEach _this;