Raised This Month: $275 Target: $400
 68% 

Solved Suggestions on randoming


Post New Thread Reply   
 
Thread Tools Display Modes
Airkish
AlliedModders Donor
Join Date: Apr 2016
Location: Lithuania
Old 07-14-2018 , 16:57   Re: Suggestions on randoming
Reply With Quote #11

Quote:
Originally Posted by KliPPy View Post
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
Airkish is offline
fysiks
Veteran Member
Join Date: Sep 2007
Location: Flatland, USA
Old 07-14-2018 , 18:09   Re: Suggestions on randoming
Reply With Quote #12

Quote:
Originally Posted by KliPPy View Post
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%.
Well, I assumed that adding up to 100 was a trivial task which is should be.

If you don't want to do the math beforehand, you can simply replace

Code:
rand = random(100)
with

Code:
	i = sum = 0
	for( i = 0; i < count; i++ )
	{
		sum += itemChances[i]
	}
	rand = random(sum)
But realize that if they don't add up to 100, the values basically have no meaning, they're just arbitrary. Though, I can think of some minor use cases to do this to reduce the amount of math required to adjust probabilities.

Quote:
Originally Posted by Airkish View Post
It always return first number from array
Did you even try mine? It's super simple and it works. You can play around with the numbers to get what you need. If you don't know how to do the adding up to 100 thing, you can do the code replacement I mentioned above. It will be more efficient than Klippy's function.
__________________

Last edited by fysiks; 07-14-2018 at 18:32.
fysiks is offline
Airkish
AlliedModders Donor
Join Date: Apr 2016
Location: Lithuania
Old 07-15-2018 , 04:11   Re: Suggestions on randoming
Reply With Quote #13

Thanks everyone for help, solved using fysiks suggestions.
Airkish is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:50.


Powered by vBulletin®
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Theme made by Freecode