Thread Tools Display Modes
06-06-13, 12:33 AM   #1
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
random()

Hi all,

Is possible that the function:

random(1,n)

called with a short delay (let's say 1.5 sec) one from each other will return several time in a row the same value (es y). And this is more visible if "n" is not so much far from 1 so that the numbers to randomize are few.

es. of output I mean (1..4) : 2,2,2,2,2,3

Is possible to add some more entropy to this function or rewrite it in other way (es. scaling the number to something larger ?) to get something like:

1,4,3,3,2,4,1 etc etc ...


Thanks for attention.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
06-06-13, 12:41 AM   #2
p3lim
A Pyroguard Emberseer
 
p3lim's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 1,710
Nope, that's the point of the function, it's random, and still unlikely you might get the same number over and over again.

Mind if I ask what you need this for?
  Reply With Quote
06-06-13, 01:22 AM   #3
humfras
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Oct 2009
Posts: 131
Every number has the same possibility: 1/(number of values)
In your example (1-4), the chance of having the same number again is 25%, that's quite a lot.

If you want to 'block' a specific number for a given time, you'll need an extra OnUpdate script that handles a blacklist.
Or you fix it with a looping function that loops until the current random number is different to the previous.
__________________
Author of VuhDo CursorCastBar OptiTaunt Poisoner RaidMobMarker
  Reply With Quote
06-06-13, 03:00 AM   #4
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
If you want a number to only swap every so and then you can work with microtime.
Just cut of as many numbers on the end as you like.

Basically you can cout out the "seconds" counter ranging from 0..9. If you need some fine tunings you can still do operations on that one.

72345344412222
72345344412222

I used sth similar on a picture swapper that changes pictures with a preset order based on a number calculated by microtime cut-off.

There are tons of other ways though.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 06-06-13 at 03:05 AM.
  Reply With Quote
06-06-13, 09:42 AM   #5
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
If you dont want to have a number that is following itself (did I explain that correctly) I'm suggesting something like this:
lua Code:
  1. local random
  2. do
  3.     local rand = math.random
  4.     local x, y
  5.     function random(...)
  6.         repeat
  7.             x = rand(...)
  8.         until x ~= y
  9.         y = x
  10.         return x
  11.     end
  12. end

Last edited by ravagernl : 06-07-13 at 09:29 AM. Reason: /golfclap me
  Reply With Quote
06-06-13, 10:05 AM   #6
TSquared
Big Daddy!
Join Date: May 2008
Posts: 527
If you want to constrict your random range you can multiply the random number by the full range (ex - 0-4 is a range of 5 numbers so "myRand= floor(math.random() * 5)")

If you never want a number to go "back-to-back" you check if it's one less the range and if it's lower then the previous value just take your value, if it's higher add one.

If you want a random range that does not repeat until it goes through all the numbers you can make an array with the values in sequence and then sort them randomly. Then just pull them off in sequence.

(FYI - looping with random can take a random amount of time

Last edited by TSquared : 06-06-13 at 02:48 PM. Reason: DOH! forgot lua's random was 0,1 :P
  Reply With Quote
06-06-13, 03:08 PM   #7
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Originally Posted by p3lim View Post
Nope, that's the point of the function, it's random, and still unlikely you might get the same number over and over again.

Mind if I ask what you need this for?
A little addon that summon a random mount.
The problem is that I press the key and summon mount A, I don't want it and repress A (got same mount :-), again ... again until it changes :-) Ok, it is intended to be random, but what I'd like to remove is the effect to have a lot of times the same number picked ...

The relevant part of code is this:
Lua Code:
  1. local number=random(1,#MyCatMount_mrc[category]);
  2.         local picked=MyCatMount_mrc[category][number]:lower();
  3.         local msg=prgname .. " error: unable to summon \"" .. picked .. "\" from \"" .. category .. "\" category.";
  4.        
  5.         for index=1,GetNumCompanions("MOUNT") do
  6.             local _,name=GetCompanionInfo("MOUNT",index);
  7.             if name:lower()==picked then
  8.                 msg = prgname .. " is summoning... " .. picked;
  9.                 CallCompanion("MOUNT",index);
  10.                 break;
  11.             end
  12.         end

Thanks for your answer anyway.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
06-06-13, 03:21 PM   #8
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Thanks very much for all the answers. I have now a clearer idea but I need some more time to check your all answers better.

In the mean time... thanks again at all.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
06-06-13, 04:27 PM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by ravagernl View Post
lua Code:
  1. local random
  2. do
  3.     local rand = math.random
  4.     local x, y
  5.     function random(...)
  6.         repeat
  7.             x = math.random(...)
  8.         until x ~= y
  9.         y = x
  10.         return x
  11.     end
  12. end
I like how you upvalued math.random but then didn't use your upvalue.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
06-06-13, 06:41 PM   #10
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,359
This might be helpful, it's along the lines of what's discussed here with some code examples.

Randomizing an array
  Reply With Quote
06-07-13, 09:14 AM   #11
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
Originally Posted by Phanx View Post
I like how you upvalued math.random but then didn't use your upvalue.
LOL! I think I forgot. I hope the intention is clear
  Reply With Quote
06-07-13, 06:25 PM   #12
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
Best ever: http://xkcd.com/221/
  Reply With Quote
06-07-13, 08:32 PM   #13
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Dridzt View Post
This might be helpful, it's along the lines of what's discussed here with some code examples.

Randomizing an array
I would think it's less taxing on the system to just pick a random index rather than to shuffle the entire table.

At any rate, I think this would be a more efficient way. Instead of repeatedly calling math.random() until it returns a different number, you have it randomize to one less than the max and add one if the random number returned is greater than or equals the last number returned.
Lua Code:
  1. local RandFunc,LastMin,LastMax,LastRand=math.random;
  2. function UniqueRandom(min,max)
  3.     if not max then min,max=1,min; end--    If min given, but not max, assume 1 to X
  4.     if not max then return RandFunc(); end--    if min and max not given, just return float random
  5.     if min<max then return nil; end--   Errors if min greater than max
  6.     if min==max then return min; end--  Equal min and max return that number
  7.  
  8.     if min~=LastMin or max~=LastMax then
  9. --      Initialize our variables or reset if ranges changed
  10.         LastMin,LastMax,LastRand=min,max,RandFunc(min,max);
  11.     else
  12.         local rand=RandFunc(min,max-1);--   Decrease range max by 1
  13.         if rand>=LastRand then rand=rand+1; end--   Add 1 if rand >= last result
  14.         LastMin,LastMax,LastRand=min,max,rand;
  15.     end
  16.     return LastRand;
  17. end



Originally Posted by Rainrider View Post
Good one. Would be better if it returned 1 instead of 4. It would be a more realistic d4 roll then.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 06-07-13 at 08:35 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » random()

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

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