| 12-12-2011, 06:09 PM | #1 |
JASS:library PseudoRandom globals private integer seed = 1 endglobals //===================================================================== // Return pseudorandom integer that can be used as struct/array index // Has full number period (8190). // Do not change constants - you will get non-optimal period //===================================================================== public function Index takes nothing returns integer set seed = seed * 5 + 17 set seed = ModuloInteger(seed, 8192) if seed == 0 then set seed = 17 elseif seed == 8191 then set seed = 12 endif return seed endfunction endlibrary Tested the function with array sorting. All numbers are there except number 22. (talk about weird math) Not much but it does its job. Wish we had a section for jass functions like on that site I used so long ago I can't even remember it's name.... |
| 12-12-2011, 10:15 PM | #2 |
Would you care to provide a sample use case? I can't think of any reason to go through the whole index range of an array randomly. Why wouldn't there be 22? 5+17=22 if im not totally mistaken. Does this generate each index once? What happens after 8192 steps? You meant this site? EDIT: So this actually generates every possible index exactly once... How the hell did you create a function like this? I would totally prefer a small tutorial on how to create those functions over this snippet. xD |
| 12-12-2011, 11:15 PM | #3 | |||
Quote:
I guess all numbers are there. Quote:
Btw 8192 is the biggest Galois group you can create with 32-bit jass integers without getting negative values due to overflow, a really lucky coincidence. :) Quote:
I was hacking around jasshelper and when I saw function vexorian was using for generating hashtable keys I got a headache so I created a proper one. Than I thought it might be useful to someone in the map as well so I created a jass version too. |
| 12-13-2011, 07:05 AM | #4 |
Unfortunately, array index 8191 can bug out so the effective limit is actually 8190. |
| 12-13-2011, 07:39 AM | #5 |
Wasn't that fixed with one of the latest patches? If not I just need to add one if statement there. Remind me what was that bug about? Something about campaigns I think... |
| 12-13-2011, 09:32 AM | #6 |
The values stored under that index don't get saved correctly when you save a game or something like that. |
| 12-13-2011, 10:20 AM | #7 |
Updated to skip indexes 0 and 8191 because they can be problematic. |
| 12-13-2011, 03:00 PM | #8 |
Okay. Now please also tell me what this is supposed to be useful for. |
| 12-13-2011, 03:53 PM | #9 |
Pseudorandom numbers are generally always useful when you want to have random things, but also have them repeat in the exact same order for the same input values. Remember this option from WE: File -> Preferences -> Test Map -> Use Fixed Random Seed. Great stuff for debugging random events. In vJass compiler it is used for: Generating random names for 'secret' initstruct functions. Generating random prefixes for private members of scopes and libraries. Generating nicely distributed hashtable keys that can also be used as jass array indexes. (keyword key) |
| 12-13-2011, 04:33 PM | #10 |
1. InitStruct functions can just use "private keyword initStruct" 2. Random prefixes are handled by the vJass preprocessor 3. Structs generate a unique integer, too, I can't imagine why you'd want the keys 18 and 56, for example, instead of just 1 and 2. However you can easily recycle those whereas there would be a bit of issues trying to recycle with this, including a fairly consistent scraping of the max array bounds which brings a lot of trouble for efficiency. Compare that to structs which keep the indices as low as possible. I'm not saying this doesn't have some use, it's just that the reasons you gave are not good reasons. Just looking at it sparks creativity for me, I just don't know of anything specific, offhand. I will let you know if something comes to mind. |
| 12-13-2011, 05:19 PM | #11 | |
Quote:
That is it is used in the compiler version I am doing right now. pascal://============================================================================== // Some things need to be random, yet compiled map should always be the same. // So we use fixed random seed and pseudorandom number generator. // Number is kept positive because we use it in random names. // It is also always between [1..8190] so it can be used as array index as well //============================================================================== unit PseudoRandom interface function GetPseudoRandom(): integer function GetPrivatePrefix(): string function GetHashtableKey(): string //============================================================================== // WARNING: Do NOT change any constants in this file. //============================================================================== implementation uses SysUtils var name_seed : integer = 1 key_seed: integer = 1 alternator: boolean = false //============================================================================== // PRIVATE: generates next pseudo random number for a given seed. //============================================================================== procedure NextPseudoRandom(var seed:integer) begin seed := seed * 5 + 17 seed := seed mod 8192 if seed < 0 then seed := seed + 8192 if seed = 0 then seed := 17 if seed = 8191 then seed := 12 end //============================================================================== // This function is called once for every line of text jasshelper parses. // It is used to generate random names. // You always get same random names for same script input. (pseudorandom) //============================================================================== function GetPseudoRandom(): integer begin NextPseudoRandom(name_seed) Result := name_seed end //============================================================================== // Pseudo random hashtable keys. //============================================================================== function GetHashtableKey:string begin NextPseudoRandom(key_seed) Result := IntToStr(key_seed) end //============================================================================== // Returns random prefix for private stuff in scopes and libraries. //============================================================================== function GetPrivatePrefix():string begin if (GetPseudoRandom() mod 2 = 0) then Result := '__' else Result := '___' end end. EDIT: In case someone wonders why I put this into jasshelper, it is because Vex was using real random numbers, That means that you could not test-compare two compiled outputwar3map.j files because you always get different results. This way same input script always produces same output script. But if you change a single line of code it changes all random stuff. (names, prefixes, keys) |
| 12-13-2011, 05:51 PM | #12 | |
Quote:
|
| 12-13-2011, 06:06 PM | #13 |
The built in generator produces random integers, this produces random array indexes (in circular fashion, without repeating indexes until it does all 8190). If you are asking about specific use case in a map I don't know any because resource did not exist before. But I can bet you now that it does exist someone will come up with a reason to use it. Replayable Random events in RPG, save/load codes, who knows, there is a lot of crazy people out there. |
| 12-13-2011, 09:18 PM | #14 | |
Quote:
|
| 12-13-2011, 10:06 PM | #15 |
He is just following the vJass struct standard : null instance == 0 Ofc there is no problem of using the index 0 of an array variable by itself. And for the index 8191, it makes a saved game unabled to be loaded (wc3 crashes), but i have not tested if this lame bug was fixed ot not in the newest patches. |
