views:

52

answers:

2

Could someone please suggest a good way of taking a global seed value e.g. "Hello World" and using that value to lookup values in arrays or tables.

I'm sort of thinking like that classic spacefaring game of "Elite" where there were different attributes for the planets but they were not random, simply derived from the seed value for the universe.

I was thinking MD5 on the input value and then using bytes from the hash, casting them to integers and mod them into acceptable indexes for lookup tables, but i suspect there must be a better way? I read something about Mersenne twisters but maybe that would be overkill.

I'm hoping for something which will give a good distrubution over the values in my lookup tables. e.g. Red, Orange, Yellow, Green, Blue, Purple

Also to emphasize I'm not looking for random values but consistent values each time.

Update: Perhaps I'm having difficulty in expressing my own problem domain. Here is an example of a site which uses generators and can generate X number of values: http://www.seventhsanctum.com

Additional criteria

I would prefer to work from first principles rather than making use of library functions such as System.Random

+2  A: 

My approach would be to use your key as a seed for a random number generator

public StarSystem(long systemSeed){
    java.util.Random r = new Random(systemSeed);
    Color c = colorArray[r.nextInt(colorArray.length)]; // generates a psudo-random-number based from your seed
    PoliticalSystem politics = politicsArray[r.nextInt(politicsArray.length)];
    ...
}

For a given seed this will produce the same color and the same political system every time.

For getting the starting seed from a string you could just use MD5Sum and grab the first/last 64bits for your long, the other approach would be to just use a numeric for each plant. Elite also generated the names for each system using its pseudo-random-generator.

for(long seed=1; seed<NUMBER_OF_SYSTEMS; seed++){
    starSystems.add(new StarSystem(seed));
}

By setting the seed to a known value each time the Random will return the same sequence every time it is called, this is why when trying for good random values a good seed is very important. However in your case a known seed will produce the results your looking for.

The c# equivalent is

public StarSystem(int systemSeed){
    System.Random r = new Random(systemSeed);
    Color c = colorArray[r.next(colorArray.length)]; // generates a psudo-random-number based from your seed
    PoliticalSystem politics = politicsArray[r.next(politicsArray.length)];
    ...
} 

Notice a difference? no, nor did I.

David Waters
Example are in java and use Java's Random.nextInt(int maxValue) which returns a integer in the range 0-maxValue. All other main stream languages have equivalent.
David Waters
The other thing to note in my answer is that c# and Java's Random number class both have a method that will return an integer in a given range. in this case between 0 and the length of the array, giving you an easy and safe translation between random number a lookup into your color list. More formally 0 <= NextRandom < arrayLength.
David Waters
Thanks, I'm sure this will work. I was hoping someone knew an all in one answer based on first principles. i.e. the hash and the pseudorandom all in algorithm one but maybe I just wasn't seeing the wood for the trees
PeanutPower
+1  A: 

Many common random number generators will generate the same sequence given the same seed value, so it seems that all you need to do is convert your name into a number. There are any number of hashing functions that will do that.

Supplementary question: Is it required that all unique strings generate unique hashes and so (probably) unique pseudo-random sequences. ?

anon
Nope collisions are fine
PeanutPower