Home   Help Search Login Register  

Author Topic: Random Command  (Read 936 times)

0 Members and 1 Guest are viewing this topic.

Offline Ding

  • Contributing Member
  • **
  • Jurassic Park
Random Command
« on: 07 Nov 2005, 08:29:13 »
Im realy confused on how the Random Script command is used, i want to make units speak a sound randomly,

e.g.

Unit1 say "random"
~5
Unit2 say "random"
~5
Unit3 say "random"

can someone give me an example of how to do this? :), or if htere is a tutorial give a link to it :)

thanks,
ding.
"If I remain lost and die on a cross, atleast I wasn't born in a manger"

Offline THobson

  • OFPEC Patron
  • Former Staff
  • ****
Re:Random Command
« Reply #1 on: 07 Nov 2005, 09:00:05 »
Code: [Select]
_speaches = ["sound1","sound2"...]

#another
_sound = random count _speaches
_sound = _sound - (_sound % 1)
if (_sound >= count _speaches) then {goto"another"}
unitname say (_speaches select _sound)

And please don't anyone tell me I don't need the if then goto line.  It is just me.
« Last Edit: 07 Nov 2005, 09:02:25 by THobson »

Offline Raptorsaurus

  • Editors Depot Staff
  • *****
Re:Random Command
« Reply #2 on: 08 Nov 2005, 03:39:30 »
THobson,

I understand why you have the if-then.  It is in case of that very remote chance of the random command yeilding the upper limit integer.  But, if it does so, why pick another random value?  Why not this?:

Code: [Select]
if (_sound >= count _speaches) then {_sound = (count _speaches) - 1}
This would avoid the added label and goto.
« Last Edit: 08 Nov 2005, 03:46:47 by Raptorsaurus »

Offline Ding

  • Contributing Member
  • **
  • Jurassic Park
Re:Random Command
« Reply #3 on: 08 Nov 2005, 06:07:00 »
thosons script worked for what i wanted it for

_unit = _this select 0
_speaches = ["05","02","03","04","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22"]

#another
_sound = random count _speaches
_sound = _sound - (_sound % 1)
if (_sound >= count _speaches) then {goto"another"}
_unit say (_speaches select _sound)

it worked perfectly for the a.i. saying random sounds :) thanks, if anyone can add to this please do, as i am still interested how the random command can be made to use better and for other things e.g. game logics.
"If I remain lost and die on a cross, atleast I wasn't born in a manger"

Offline THobson

  • OFPEC Patron
  • Former Staff
  • ****
Re:Random Command
« Reply #4 on: 08 Nov 2005, 09:00:21 »
Raptosaurus:
The reason I do it this way is to do with my anal retentiveness.  If the if statement is ever actioned then simply to decrement the number by 1 would increase the probability of the last element in the array being chosen.  Ridiculous on my part as I doubt the random number generator is sufficiently random that this tiny increase would be noticeable.

In fact so many people have written this type of code without the if then goto statement without getting the dreaded divide by zero error that comes from trying to select an element beyond the end of the array that I suspect the statement is unnecessary.

Slapstick

  • Guest
Re:Random Command
« Reply #5 on: 09 Nov 2005, 03:01:56 »
Hi all,

I just wanted to toss in a comment so my very first post here might be usefull ;)

If you want to be as efficient as possible, and you are not concerned about a perfectly random distribution, you can do away with converting the float to an integer.  OFP is perfectly happy with something like:

_pi = 3.14159
_n = [0,1,2,3,4] select _pi

The only thing to keep in mind is the when converting floats to array indices OFP rounds off the value, it doesn't truncate.  This means the first and last elements of the array are less likely to be selected that the others unless you do some other arm waving.  If you're just selecting a random speaker it doesn't really matter if the distribution is perfectly random, and with some creative thinking this could probably be used as a "feature".   So, my version would look like:

; untested
_unitlist = units group player
_speaker = _unitlist select random ((count _unitlist) - 0.500001)
...

There is no need for the if statement here as the random function will never pick an out of range value; if there are N elements in the array, then the indices are 0 to N-1 and the random function will return a maximum value of  N-0.500001, which will be round down to N-1 when its used as an array index.

Finally, if you do want an almost perfectly random distribution then try:

_unitlist = units group player
_i = random ((count _unitlist) - 0.000001)
_i = _i - (_i % 1)
_speaker = _unitlist select _i

Now the index value will be rounded down to values in the range 0 to N-1 as random will never return exactly N.

@THobson:

Whether steps to avoid possible failures is necessary depends on your defintions of "necessary" I guess.  Is it necessary that your script _never_ fail?  Or are you happy with the script possibly failing for random people at random times?  Granted the likelyhood of getting an out of range value is small, it is not zero, so being anal is never a "Bad Thing". ;)  

And to tell you the truth I thought you were doing it for different reasons.  15 years of C++ programming and I totally missed that there was a change (albeit small) that you might get an out of range value!!!

I also agree with you re: the mod function (mentioned in another thread on a similar topic). It's too bad BIS didn't suppy a real mod function... and a random function that returned integer values instead of reals.

Offline THobson

  • OFPEC Patron
  • Former Staff
  • ****
Re:Random Command
« Reply #6 on: 09 Nov 2005, 08:55:43 »
Quote
Is it necessary that your script _never_ fail?
Yes.  That's what I try for anyway.  Not always with total success.

I always meant to test what would happen in ofp if youselected an array element using a real index.  So it rounds?  That is interesting.  Without care it would increase the possibility of an out of bounds error I presume.
« Last Edit: 09 Nov 2005, 08:57:52 by THobson »

Slapstick

  • Guest
Re:Random Command
« Reply #7 on: 09 Nov 2005, 17:45:43 »
Yes, I was surprised to find that it rounds the indices as well, I had innocently assumed that it would simply truncate the fractional part.  It was only while debugging the "Out of Bounds" errors that I discovered OFP rounds the values... how very un-handy :(