How GetRandomPercent works

Post » Tue May 17, 2011 6:07 am

Bear in mind that a lot of the below will be flowing from noobish assumptions & poor math skills :tongue:

Question 1:

wiki says:
set randVal to min + GetRandomPercent * (max-min) / 99


Now ive always had a problem with math so it seems to me that if i wanted, ex a min of 1 and a max of 4, i should have a 25% chance of getting any number within that range. But it seems to me that it will ever result in a "4" if GetRandomPercent returns a 99 since even 98 produces:

=>1 + 98 * 3 / 99
=>1 + 294 / 99
=>1 + 2.96967
=>3.96967

so it seems that instead of a 1 in 4 chance of a "4" appearing, its only a 1 in 99.


Question 2:

How will making the variable an INT or a FLOAT make a diff? i just want an integer returned. dont care for decimal values.

Thanks!
User avatar
Dustin Brown
 
Posts: 3307
Joined: Sun Sep 30, 2007 6:55 am

Post » Tue May 17, 2011 12:30 am

I am not aware of any formal language definition for whatever the scripting language is. In most languages, floats and ints are stored differently and there is a function which converts from floats to ints. Each language may have a different, exact definition of this conversion function, and I don't know what "ours" is. Some languages "truncate" and some "round". Truncating, obviously, removes all the numbers after the decimal. Rounding adds 0.5 and then truncates. In your example you truncated and you are correct that 4 is much less common. If "our" language rounds, then the distribution is 25/25/25/25.
User avatar
Leanne Molloy
 
Posts: 3342
Joined: Sat Sep 02, 2006 1:09 am

Post » Tue May 17, 2011 7:45 am

Without using a lot of math the easiest way to get a 1 in 4 chance is like this.

short vRandSet vRand to GetRandomPercentif vRand < 25   ;do stuff elseif vRand < 50   ;do stuff elseif vRand < 75   ;do stuff elseif vRand < 100   ;do stuffendif


If your math is producing numbers between 0 and 4 then use a float, and you would check the same way.

< 1< 2< 3< 4


As far as I know short variables are truncated where everything after the decimal is removed.
User avatar
Manuel rivera
 
Posts: 3395
Joined: Mon Sep 10, 2007 4:12 pm

Post » Tue May 17, 2011 8:35 am

As far as I know short variables are truncated where everything after the decimal is removed.

If that is true, then the one line solution to get even distribution is:
int iVal
set iVal to 0.5 + min + GetRandomPercent * (max-min) / 100
OK, that is two lines, but I want to make the point that iVal should not be declared as float.
User avatar
BRIANNA
 
Posts: 3438
Joined: Thu Jan 11, 2007 7:51 pm

Post » Tue May 17, 2011 8:44 am

=>1 + 98 * 3 / 99
=>1 + 294 / 99
=>1 + 2.96967
=>3.96967

so it seems that instead of a 1 in 4 chance of a "4" appearing, its only a 1 in 99.


Correct. The GECK-Wiki formula is wrong. In case of doubt, always refer to the http://cs.elderscrolls.com/constwiki/index.php/GetRandomPercent. To get a number between 1 and 4 with almost equal chances you use:

1 + 4 * getrandompercent / 100
or
1 + 0.04 * getrandompercent


Question 2:
How will making the variable an INT or a FLOAT make a diff? i just want an integer returned. dont care for decimal values.


1. Floats always have decimal places. Due to the way the computer handles them, you'll get some decimal places whenever you don't divide a power of 2 by another (smaller) power of 2. For example, 9 / 3 may result in something like 3.00000012 and "If variable == 3" will not be true.

2. With very high float values (more than 7 digits) the lower digits will be set to 0, So if you set a float variable to 123456789, the variable will actually get the value 123456700.
User avatar
Bigze Stacks
 
Posts: 3309
Joined: Sun May 20, 2007 5:07 pm

Post » Tue May 17, 2011 5:36 am

yeah that's the way i did it from way before but i was hoping to learn a more "elegant" or shorter way of doing it since that way gives a longer script and it always made me feel silly when i saw a script that does in 1 line what i did in 10 :facepalm:

anyway, the 1 to 4 was only an example. the if, elseif way could get very long if one wanted a bigger min/max than just 1 and 4.

from what davidallen said, maybe the geck does round then truncate so that the quote i gave from the wiki would work.

EDIT: made the above post while JOG was making his, i guess. again JOG i am indebted to you. someone should change that geck wiki then. that incorrect entry made me bother people more than necessary :D
User avatar
scorpion972
 
Posts: 3515
Joined: Fri Mar 16, 2007 11:20 am

Post » Tue May 17, 2011 4:55 am

Someone should change that geck wiki then. that incorrect entry made me bother people more than necessary :D


Yes, the Geck-Wiki seems to be a bit neglected... FNV specifics are rare, and several pages back from FO3 are just linking to the TESC Wiki.

(On the other hand the TESC Wiki still presents the wrong formula very prominently. I haven't corrected it back then for some reason, and nobody bothered to do so after I left... FIXED on both Wikis.)
User avatar
Andrew Perry
 
Posts: 3505
Joined: Sat Jul 07, 2007 5:40 am

Post » Tue May 17, 2011 4:03 am

If that is true, then the one line solution to get even distribution is:
int iVal
set iVal to 0.5 + min + GetRandomPercent * (max-min) / 100

This would lead to loaded results, though:
 0 - 16 = 1 (17%)17 - 49 = 2 (33%)50 - 83 = 3 (34%)84 - 99 = 4 (16%


min + GetRandomPercent * (max-min) / 99 results in:
 0 - 32 = 1 (33%)33 - 65 = 2 (33%)66 - 98 = 3 (33%)99      = 4 (1%)


min + GetRandomPercent * (max-min+1) / 100 results in:
 0 - 24 = 1 (25%)25 - 49 = 2 (25%)50 - 74 = 3 (25%)75 - 99 = 4 (25%)

User avatar
Monika Krzyzak
 
Posts: 3471
Joined: Fri Oct 13, 2006 11:29 pm

Post » Tue May 17, 2011 8:46 am

You are right about the +1, and unless somebody knows for sure whether the language truncates or rounds, we cannot conclude about the +0.5.
User avatar
JAY
 
Posts: 3433
Joined: Fri Sep 14, 2007 6:17 am

Post » Tue May 17, 2011 4:26 pm

You are right about the +1, and unless somebody knows for sure whether the language truncates or rounds, we cannot conclude about the +0.5.


Floats are truncated upon storing into an int, but floating point calculations are finished as such first. 6.789 * 100 will result in 678 not 600 or 679.
User avatar
Breautiful
 
Posts: 3539
Joined: Tue Jan 16, 2007 6:51 am

Post » Tue May 17, 2011 4:08 pm

yeah that's the way i did it from way before but i was hoping to learn a more "elegant" or shorter way of doing it since that way gives a longer script and it always made me feel silly when i saw a script that does in 1 line what i did in 10 :facepalm:

anyway, the 1 to 4 was only an example. the if, elseif way could get very long if one wanted a bigger min/max than just 1 and 4.


I don't understand how adding some math functions is going to save you from how many lines you have to check to get a result. In a 1 in 4 chance you have to do at least 3 checks followed by an else no matter what math you use. Seems having the math function at all adds unneeded processing to the script; when below you are going to have to check for each result anyway.

Maybe you can post an example, where it saves you some checks, to help me understand this.
User avatar
Curveballs On Phoenix
 
Posts: 3365
Joined: Sun Jul 01, 2007 4:43 am

Post » Tue May 17, 2011 5:15 am

I don't understand how adding some math functions is going to save you from how many lines you have to check to get a result. In a 1 in 4 chance you have to do at least 3 checks followed by an else no matter what math you use. Seems having the math function at all adds unneeded processing to the script; when below you are going to have to check for each result anyway.

Maybe you can post an example, where it saves you some checks, to help me understand this.


It always depends on the application. A live example from my WIP: A wardrobe with a secret drawer.
To find it, the player needs 6 perception, but the check is modified by a random bonus or penalty from high or low luck:

			set check to (player.getav luck - 5) * GetRandomPercent / 100 + ( player.getav perception )			if ( check >= 6 )				showmessage 001CheckSecretDrawer				set found to 1				set msgup to 1			else


So while Luck 4-6 has no effect, with 7 Luck, there is a 50% chance to find it with just PER 5, and with 3 Luck there is a 50% chance to miss it with 6 PER. 10 Luck increases the chance to find it with PER 5 to 80%, it's still 60% with PER 4 and so on.

Of course it would have been possible to make with an if-construct, but it would have been much larger and harder to read.


A less esoteric variant would be rewarding the player with a random amount of caps that still is a round sum.
(e.g. 1100, 1200 ... 1900, 2000)

short capsset caps to Getrandompercent / 10   ;// make it 0-9set caps to caps * 100 + 1100       ;// second line required to truncate decimal placesplayer.additem Caps001 caps

vs.
short capsset caps to Getrandompercentif caps < 10	set caps to 1100elseif caps < 20	set caps to 1200elseif caps < 30	set caps to 1300elseif caps < 40	set caps to 1400elseif caps < 50	set caps to 1500elseif caps < 60	set caps to 1600elseif caps < 70	set caps to 1700elseif caps < 80	set caps to 1800elseif caps < 90	set caps to 1900else	set caps to 2000endifplayer.additem Caps001 caps

User avatar
Dan Wright
 
Posts: 3308
Joined: Mon Jul 16, 2007 8:40 am

Post » Tue May 17, 2011 6:11 am

mine was a lot simpler than JOG's. my mod makes the chances and result of successfully harvesting from plants and collecting loot from creatures depend on the survival skill. instead of a static 1 or 2 fruits from plants, for example, the player may fail to harvest anything or, if successful, harvest a bonus amount of up to 4 (tentative amount) extra fruits (thus the need for a min/max). so no matter the range, i can just write:
set BonusFruits to min + GetRandomPercent * (max-min + 1)/100player.additem NVBananaYuccaFruit BonusFruits

User avatar
Gemma Archer
 
Posts: 3492
Joined: Sun Jul 16, 2006 12:02 am

Post » Tue May 17, 2011 4:20 pm

Thanks for the examples. Always nice to find ways to make scripts smaller. I wasn't considering that the returned number was going to be used as an item count. My thoughts were more along the lines of 4 different actions being possible, where every one would have to be checked, something like moving the player to one of four random locations.
User avatar
CORY
 
Posts: 3335
Joined: Sat Oct 13, 2007 9:54 pm


Return to Fallout: New Vegas