I'm creating a game where I want to create random worlds and give the player the option of having the same world made again by entering the same seed...
So... How can I do this? It will generate the same set of numbers, but not the same every time you call for the random function...
Do I have to make function of sorts based on the seed manually?
In GameMaker Studio and GameMaker 8.1 there is a function:
random_set_seed(seed)
Here you can enter your seed.
Then random(x) gives the same n-th result per game run.
random(100)
randomize() // This doesn't change rand[0] or rand[1]
random_set_seed(20) // because of this
rand[0]=random(100)
rand[1]=random(100)
Randomizer functions either use mathematical formulas which seem to give out random numbers or just look at an already calculated array of seemingly random numbers and return them in order. In most languages, there is a function which will look at the computer's clock and will use this value as a first value for the mathematical formula or as a starting index in the pseudorandom array. In GameMaker, you can use randomize() to do that. Only call that once when the game launches and you'll get different results on every execution.
If you want the opposite, that is you want to be able to regenerate the same seemingly random sequence, you can instead set the seed manually with random_set_seed(value). The value passed needs to be a number. Then you can give that seed to the player.
So if you want to generate a random level on the first time and later be able to replay the same level, you need to do in order:
Call randomize to set a random seed.
Call random_get_seed which will return the current seed.
Call random and the likes to generate a level.
When the player wants to use the same seed as before, call random_set_seed and pass it the seed.
Warning: By using those functions, you are putting your trust in GM's randomizing functions. These are platform dependent, and the functions might change in a later version of GM. If you want your seeds to work across all platforms and versions of your game, you might want to work on your own randomizing functions.
Related
I'm trying to create a game, which I want to always run the same given the same seed. That means that random events - be them what they may - will always be the same for two players using the same seed.
However, given the user's ability to save and load the game, Ruby's Random would reset every time the save loaded, making the whole principle void if two players save and load at different points.
The only solution I have imagined for this is, whenever a save file is loaded, to generate the same number of points as before, and thus getting Ruby's Random to the same state as it was before load. However, to do that I'd need to extend it so a counter is updated every time a random number is generated.
Does anyone know how to do that or has a better way to restore the state of Ruby's Random?
PS: I cannot use an instance of Random (Random.new) and Marshall it. I have to use Ruby's default.
Sounds like Marshal.dump/Marshal.load may be exactly what you want. The Random class documentation explicitly states "Random objects can be marshaled, allowing sequences to be saved and resumed."
You may still have problems with synchronization across games, since different user-based decisions can take you through different logic paths and thus use the sequence of random numbers in entirely different ways.
I'd suggest maybe saving the 'current' data to a file when the user decides to save (or when the program closes) depending on what you prefer.
This can be done using the File class in ruby.
This would mean you'd need to keep track of turns and pass that along with the save data. Or you could loop through the data in the file and find out how many turns have occurred that way I suppose.
So you'd have something like:
def loadGame(loadFile)
loadFile.open
data = loadFile.read
# What you do below here depends on how you decide to store the data in saveGame.
end
def saveGame(saveFile)
saveFile.open
saveFile.puts data
end
Havent really tried the above code so it could be bad syntax or such. It's mainly just the concept I'm trying to get across.
Hopefully that helps?
There are many generators that compute each random number in the sequence from the previous value alone, so if you used one of those you need only save the last random number as part of the state of the game. An example is a basic linear congruential generator, which has the form:
z(n+1) = (az(n) + b) mod c
where a, b and c are typically large (known) constants, and z(0) is the seed.
An arguably better one is the so-called "mulitply-with-carry" method.
I writing an application in AVR Studio 4 which generates random numbers and outputs them on a seven segment display. At the moment i am using a seed, the seed value then gets randomized and the value output. This method obviously produces the same random number sequence (and displays the same sequence) every time the program is run. Is there an alternate method i can use which does not use a seed and as such does not start the program with the same number each time, allowing for different random numbers.
Thanks
Each time the microcontroller starts up it is seeing exactly the same internal state as any other time it starts up. This means its output will always be the same regardless of any algorithm you might use.
The only way to get it to produce different behaviour is to somehow modify its state at startup by introducing some external information or by storing state between startups. Some ideas for how to do the first option might be to measure the duration of a user key press (if your system has buttons) or sensing a temperature or other external input and using this to seed the algorithm. However the simplest option is probably to just store a counter in EEPROM that is incremented after each startup and use this to generate the seed.
I hope it's not too obvious a question: is there a random number generation algorithm that doesn't depend on previously returned values, so that I can get (for example) the 50th number in the sequence, without computing the previous 49?
The reason is that I am making roguelike that will be persistent (so that I can recreate the exact same level from the same seed), but to compute certain features of each level, I don't want to have to "compute" all previous features just to get the random number generator to the correct "state" of having been used, for example, 100 times so far. I would like to be able to query the 101st random number without determining previous values so that the program can create level features separately.
You can encrypt ordinary sequence number [1..N] with any cipher,
and by this way - generate unique pseudorandom value for each SeqNo.
If you use a linear congruential random number generator, it is trivial to compute the $n$-th element generated from a given seed. But it is probably easier just to stash away the state at the "interesting" points of the game.
OTOH, if you want to "restart" the game at a certain point, you'll presumably want to be able to recreate the dungeon's features, but (due to different player actions) the RNG usage will be different from then on. I.e., if started at the same point, if I shoot twice at a monster the RNG will be used more times than if I just run away; the next item generated will get different values. Perhaps what you really want is several independent random number streams, and saving the states as needed?
There are lots of roguelike games around, mostly open source. Some are limited/small (from "build a game in a day" sort of competitions), and might make a good starting point for you. Why start your own, and not hack on an existing one?
When we need a random number we use srand once to initialize the seed and after that we can use rand. Why do we need to seed using srand? For example srand(time(Null)); Can't we just use rand() % 99999? Am I missing something in the concept of these functions?
Here's the thing,
You actually don't need to seed your random number generator. Go ahead, try it without!
BUT, you will always get the same sequence of 'random' numbers.
Pseudo-random number generators such as rand() only generate random-looking sequences. If you just start them from the 'beginning' every time, they will of course look the same.
Seeding the generator is a good way to get numbers that actually appear 'properly' random. If you seed with the time, you are starting somewhere 'random' in the sequence. Note that picking time values close together usually gives two sequences that are also very different.
You can seed with whatever you like. For example, if you have lots of threads using lots of generators, the time is a bad idea because the time may well be the same for multiple threads.
There is no clear 'good' value for the seed, so it is usually not seeded by default. This can also be a good thing if you want to 're-run' a randomised algorithm with exactly the same input: just set the seed to be the same seed.
srand(0) will always return the same deterministic sequence of values, although those values will appear random.
Knowing your seed will allow an attacker to determine every number you generate.
By setting a seed, you effectively create a different sequence.
srand(0) may be entirely acceptable to your needs, if you only need the appearence of random.
I read that seeds are used to initialize random number generators. But seems like the randomness of the seed doesn't matter much for getting good randomness from the generator. So I want to understand what is a seed actually? Why is it called so? And lastly why time in a computer system is used to generate such seeds?
A pseudo-random number generator produces a sequence of numbers. It isn't truly random, but generally a mathematical calculation which produces an output that matches some desirable distribution, and without obvious patterns. In order to produce such a sequence, there must be state stored for the generator to be able to generate the next number in that sequence. The state is updated each time using some part of the output from the previous step.
Seeding explicitly initialises this state. A 'seed' is a starting point, from which something grows. In this case, a sequence of numbers.
This can be used either to always generate the same sequence (by using a known constant seed), which is useful for having deterministic behaviour. This is good for debugging, for some network applications, cryptography, etc.
Or, in situations where you want the behaviour to be unpredictable (always different each time you run a program, a card game perhaps), you can seed with a number likely to be continually changing, such as time.
The 'randomness' of the sequence does not depend on the seed chosen, though it does depend on not reseeding the sequence.