No, this isn't a number generator
What & why:
It is a simple hack to give mappers the ability to reproduce random numbers.
This was developed to help me with item generation on-the-fly, sort of like action-rpg's do.
Breakdown of what this script does:
Anyway, the script was designed to be of help with item generation, and since I only expect to generate a few hundred items every game it seems enough with 8000 "random" integers.
If someone wants more (or less) "random" integers, the script supports that too, although at a big (large array overhead?) performance hit. Though, speed shouldn't really be a main concern.
A user can also force the script to only save unique integers (i.e only save integers that aren't in the array already).
At last, here's the code:
Changelog:
1.0.1 - Fixed basic usage instructions.
1.1 - Added fillTable and fillTableEx methods. Removed getRandomInt method. Removed option for generating only positive/negative integers. Small speed boost when all integers must be unique.
1.2 - Fixed error that made the system select same 'game seed' every game.
1.2.1 - Improved fillTableEx method.
1.2.1.1 - Fixed fillTableEx method.
C&C
What & why:
It is a simple hack to give mappers the ability to reproduce random numbers.
This was developed to help me with item generation on-the-fly, sort of like action-rpg's do.
Breakdown of what this script does:
- Get a random value, called 'game seed'.
- Set global seed to a fixed integer value.
- Get a couple of integers and store them in an array.
- Set global seed to 'game seed'.
- Provide a couple of methods to access the "random" integers.
Anyway, the script was designed to be of help with item generation, and since I only expect to generate a few hundred items every game it seems enough with 8000 "random" integers.
If someone wants more (or less) "random" integers, the script supports that too, although at a big (large array overhead?) performance hit. Though, speed shouldn't really be a main concern.
A user can also force the script to only save unique integers (i.e only save integers that aren't in the array already).
At last, here's the code:
JASS:
library PRNG initializer Init requires Table
globals
/**
* PRNG -- version 1.2.1.1 -- by Tukki
*
* REQUIREMENTS:
*
* Table - [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
*
*
* API:
*
* Note:
* - "random" = integer that is random, but persistent over all maps.
* - random = integer that is random, but not persistent.
*
* GLOBAL TABLE - methods that use a global array
*
* PRNG.getRandomIndex() --> index integer in range [0, GENERATOR_COUNT]
* - returns a random integer that can be used to get the "random" integers,
* for the percieved effect of randomness.
*
* PRNG.getIndexInt(integer index) --> integer at 'index' position.
* - returns the "random" integer mapped to 'index'.
* - only use natural numbers here (>=0), - will crash the game.
*
* DYNAMIC TABLE - methods that fill a table with values
*
* PRNG.fillTableEx(Table table, integer generatorSeed, integer generatorCount, integer generatorMinInt, integer generatorMaxInt, boolean forceUnique)
* - fills the provided table with random values based on the provided parameters.
*
* PRNG.fillTable(Table table, integer generatorSeed, integer generatorCount)
* - fills the table using the provided argument and the global options.
* - this method calls filLTableEx(..) with the appropriate arguments.
*
*
****************************************************************************************
*
* BASIC USE
*
* local integer a = PRNG.getRandomIndex() -- get an index
* call SetRandomSeed(PRNG.getIndexInt(a)) -- update the game seed
* call GenerateRandomItem(a) -- do something that uses GetRandom..(), tie the index value to this item.
*
* When saving, pair the item id and the generator index.
*
* When loading, to generate the same item:
*
* local integer a = myLoadedItemIndex
* call SetRandomSeed(a) -- update the game seed
* call GenerateRandomInt(a) -- should generate the same item as the one you saved.
*
*
****************************************************************************************
*
* Number of integers generated.
*
* Since the system uses an integer array, the amount of
* memory used cannot be changed. However, this value
* affects load time due to the amount of calls to GetRandomInt(..).
*/
private constant integer GENERATOR_COUNT = 8190
/**
* Forces the output integers to be truly unique.
* Requires the library Table to be present in the map.
*
* Note:
* If you have low GENERATOR_MAX_INT and GENERATOR_MIN_INT values,
* in combination with a high GENERATOR_COUNT value, setting this to true
* might crash the script, use with care. If you suspect that the script
* has crashed, check the PRNG.initialized variable.
*
* if PRNG.initialized == true : system is correctly initialized
* if PRNG.initialized == false : system has crashed somewhere
*
* Use the PRNG.lastGeneratedIntegerIndex value to find at which
* index the script crashed.
*
* PRNG.initialized and PRNG.lastGeneratedIntegerIndex are only available in debug mode.
*/
private constant boolean GENERATOR_FORCE_ALL_RANDOM = false
/**
* The maximum and minimum values of generated ints.
*
* The numbers should be in range [-2147483648,2147483647]
*/
private constant integer GENERATOR_MAX_INT = 859135902 // Expected to be positive.
private constant integer GENERATOR_MIN_INT = -859135902 // Expected to be negative.
/**
* The static value used to generate ints.
* Keep this constant for all your map versions,
* otherwise you will end up with different
* values than you expected.
*
* The number itself should be in range [-2147483648,2147483647]
*/
private constant integer GENERATOR_SEED = 90826133
endglobals
private keyword ints
struct PRNG extends array
debug public static boolean initialized = false
debug public static integer lastGeneratedIntegerIndex = 0
// STANDARD METHODS
static method getRandomIndex takes nothing returns integer
return GetRandomInt(0, GENERATOR_COUNT)
endmethod
static method getIndexInt takes integer index returns integer
return ints[index]
endmethod
// DYNAMIC TABLES
static method fillTableEx takes Table table, integer generatorSeed, integer generatorCount, integer generatorMinInt, integer generatorMaxInt, boolean forceUnique returns nothing
local integer gameSeed = GetRandomInt(-2147483648, 2147483647)
local integer v
local Table unique
if (forceUnique) then
set unique = Table.create()
endif
call SetRandomSeed(generatorSeed)
debug set PRNG.lastGeneratedIntegerIndex = 0
loop
set generatorCount = generatorCount- 1
if (forceUnique) then
loop
set v = GetRandomInt(generatorMinInt, generatorMaxInt)
exitwhen not unique.has(v)
endloop
set unique[v] = 1
set table[generatorCount] = v
else
set table[generatorCount] = GetRandomInt(generatorMinInt, generatorMaxInt)
endif
debug set PRNG.lastGeneratedIntegerIndex = generatorCount
exitwhen generatorCount == 0
endloop
// Update global seed to avoid static seeds.
call SetRandomSeed(gameSeed)
if (forceUnique) then
call unique.destroy()
endif
endmethod
static method fillTable takes Table table, integer generatorSeed, integer generatorCount returns nothing
call fillTableEx(table, generatorSeed, generatorCount, GENERATOR_MAX_INT, GENERATOR_MIN_INT, GENERATOR_FORCE_ALL_RANDOM)
endmethod
endstruct
globals
private integer array ints[GENERATOR_COUNT]
endglobals
private function Init takes nothing returns nothing
local integer i = 0
static if (GENERATOR_FORCE_ALL_RANDOM) then
local integer v
local Table unique = Table.create()
endif
// Get a new global seed, since we're overwriting the wc3-generated one.
local integer gameSeed = GetRandomInt(-214748364, 214748364)
call SetRandomSeed(GENERATOR_SEED)
loop
exitwhen i == GENERATOR_COUNT
static if (GENERATOR_FORCE_ALL_RANDOM) then
loop
set v = GetRandomInt(GENERATOR_MIN_INT, GENERATOR_MAX_INT)
exitwhen not unique.has(v)
endloop
set unique[v] = 1
set ints[i] = v
else
set ints[i] = GetRandomInt(GENERATOR_MIN_INT, GENERATOR_MAX_INT)
endif
debug set PRNG.lastGeneratedIntegerIndex = i
set i = i + 1
endloop
// Flag system as initialized, so user can detect that it has crashed.
debug set PRNG.initialized = true
// Update global seed to avoid static seeds.
call SetRandomSeed(gameSeed)
static if (GENERATOR_FORCE_ALL_RANDOM) then
call unique.destroy()
endif
endfunction
endlibrary
Changelog:
1.0.1 - Fixed basic usage instructions.
1.1 - Added fillTable and fillTableEx methods. Removed getRandomInt method. Removed option for generating only positive/negative integers. Small speed boost when all integers must be unique.
1.2 - Fixed error that made the system select same 'game seed' every game.
1.2.1 - Improved fillTableEx method.
1.2.1.1 - Fixed fillTableEx method.
C&C
Last edited by a moderator: