|
AlliedModders Donor
Join Date: Apr 2016
Location: Lithuania
|
07-14-2018
, 16:57
Re: Suggestions on randoming
|
#11
|
Quote:
Originally Posted by KliPPy
You could map your probabilities so they all add up to a total of 1, whatever their values are. I'll be expressing probabilities in the range [0, 1] but you can always multiply it by 100 to display the chance in percents.
Untested, but the same algorithm did work in JavaScript for me:
Code:
GetRandomItem(const Float:itemChances[], count = sizeof itemChances) {
new Array:mappedChances = ArrayCreate(1, 0);
new index = 0;
new Float:sum = 0.0;
#if AMXX_VERSION_NUM > 182
ArrayResize(mappedChances, count);
#endif
// Put all elements into mappedChances and accumulate
for(index = 0; index < count; index++) {
ArrayPushCell(mappedChances, itemChances[index]);
sum += itemChances[index];
}
// Map so the sum of all chances is 1
for(index = 0; index < count; index++) {
ArraySetCell(mappedChances, index, ArrayGetCell(mappedChances, index) / sum);
}
sum = 0.0;
new const Float:rand = random_float(0.0, 1.0);
for(index = 0; index < count; index++) {
sum += ArrayGetCell(mappedChances, index);
if(rand <= sum) {
break;
}
}
ArrayDestroy(mappedChances);
return index;
}
Code:
new const Float:itemChances[] = { 0.5, 0.1, 0.05, 0.15, 0.2, 0.4, 0.04, 0.06, 0.5 };
new const result = GetRandomItem(itemChances, sizeof itemChances);
As you can see, the chances in the array add up to 2.0 (or 200% percent), but in that case if you divide them by 2 they will add up to 1.0.
It's pretty much what Fysiks did but with the mapping step so input values don't have to add up to 100%.
|
It always return first number from array
|
|
|
|