Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Getting a seeded value from a list

Reply
Thread Tools

Re: Getting a seeded value from a list

 
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      11-19-2012
On Sun, 18 Nov 2012 19:00:57 -0800, Graham Fielding
<(E-Mail Removed)> declaimed the following in
gmane.comp.python.general:

>
>
>
>
> Hello! Clueless noob again! This time around, I'm trying to figure out the random.seed() function -- specifically, I'd like to retrieve the seeded values from a list (which I've called levelSeed), and use them in a random-dungeon generator. The numbers are generating and storing properly, but I can't find any examples online that aren't specific to a particular purpose (such as mathematics, arrays, and the like). Would I use 'getstate' when the dungeon is generated, or is there another method that would be better suited to the task?


The "seed" sets the initial state of the generator. After setting
the state, you just use regular random number generation to retrieve
values.

Are you generating the entire level on entry, or as each room is
"opened" (if, "as opened", you have the complication that going down a
level and back up will result in different random numbers vs going
straight to the room).

Generating on entry only needs the seed for the initial generation
point (as mentioned, first time you could use the system clock and save
the value).

getstate() is likely mostly usable when you need to interrupt the
execution of the program and need to continue the random sequence from
where it left off -- but don't need to restore prior values (in your
case, prior rooms). That is: say a weather simulation... You only need
to save the current "weather matrix" (for each point: temp, wind-speed,
wind-direction [where a "point" may be lat/long/altitude]) AND the
current state of the random number generation. Tomorrow, you just load
the saved state [one instance in time] and reseed the generator.

But for a dungeon -- you may be best served by generating the entire
level (all rooms, doors, static encounters [traps, treasure]) when
entering the level, and saving the entire dungeon (after all, after a
treasure is collected, it shouldn't re-appear the next time you start
that same level -- if you only save the starting seed, then all
encounters will also be regenerated). In this scenario, where you save
the entire dungeon, you don't even need to worry about the seed --
you'll never really want to recreate the same dungeon for another party
[unless running a competition in which case you seed every computer the
same so every participant is running the identical dungeon].
--
Wulfraed Dennis Lee Bieber AF6VN
http://www.velocityreviews.com/forums/(E-Mail Removed) HTTP://wlfraed.home.netcom.com/

 
Reply With Quote
 
 
 
 
frednotbob@hotmail.ca
Guest
Posts: n/a
 
      11-20-2012
>
> Are you generating the entire level on entry, or as each room is
>
> "opened" (if, "as opened", you have the complication that going down a
>
> level and back up will result in different random numbers vs going
>
> straight to the room).
>
>
>
> Generating on entry only needs the seed for the initial generation
>
> point (as mentioned, first time you could use the system clock and save
>
> the value).


I'm generating the room on entry -- the 'stairs' object calls 'make_map()' which creates the floor and lays out monsters and treasure.

What I'm trying to do is set a persistent state for the levels generated by make_map(), so the player can move between floors without generating a totally new randomized floor each time.

>
> But for a dungeon -- you may be best served by generating the entire
>
> level (all rooms, doors, static encounters [traps, treasure]) when
>
> entering the level, and saving the entire dungeon (after all, after a
>
> treasure is collected, it shouldn't re-appear the next time you start
>
> that same level -- if you only save the starting seed, then all
>
> encounters will also be regenerated). In this scenario, where you save
>
> the entire dungeon, you don't even need to worry about the seed --
>
> you'll never really want to recreate the same dungeon for another party
>
> [unless running a competition in which case you seed every computer the
>
> same so every participant is running the identical dungeon].



That actually sounds close to what I'd like to ?do. How would I go about saving the dungeon? I'm guessing I'd need to define how many levels to generate, first of all....
 
Reply With Quote
 
 
 
 
frednotbob@hotmail.ca
Guest
Posts: n/a
 
      11-20-2012
>
> Are you generating the entire level on entry, or as each room is
>
> "opened" (if, "as opened", you have the complication that going down a
>
> level and back up will result in different random numbers vs going
>
> straight to the room).
>
>
>
> Generating on entry only needs the seed for the initial generation
>
> point (as mentioned, first time you could use the system clock and save
>
> the value).


I'm generating the room on entry -- the 'stairs' object calls 'make_map()' which creates the floor and lays out monsters and treasure.

What I'm trying to do is set a persistent state for the levels generated by make_map(), so the player can move between floors without generating a totally new randomized floor each time.

>
> But for a dungeon -- you may be best served by generating the entire
>
> level (all rooms, doors, static encounters [traps, treasure]) when
>
> entering the level, and saving the entire dungeon (after all, after a
>
> treasure is collected, it shouldn't re-appear the next time you start
>
> that same level -- if you only save the starting seed, then all
>
> encounters will also be regenerated). In this scenario, where you save
>
> the entire dungeon, you don't even need to worry about the seed --
>
> you'll never really want to recreate the same dungeon for another party
>
> [unless running a competition in which case you seed every computer the
>
> same so every participant is running the identical dungeon].



That actually sounds close to what I'd like to ?do. How would I go about saving the dungeon? I'm guessing I'd need to define how many levels to generate, first of all....
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      11-20-2012
On Mon, 19 Nov 2012 21:45:55 -0800, frednotbob wrote:

> What I'm trying to do is set a persistent state for the levels generated
> by make_map(), so the player can move between floors without generating a
> totally new randomized floor each time.


You need to distinguish between immutable data (e.g. walls) and mutable
data (monsters, treasure). The former can be generated from the seed each
time you enter the level; the latter must be generated the first time then
stored.

If the number of levels is reasonable, you can use a PRNG to generate a
list of random numbers at game start, which are the seeds used to generate
each level.

Alternatively, you can generate a single random "game id" at game start
then generate the seed for each level from a hash of the level number and
the game id.

When it comes to random level generation, a single sequential PRNG isn't
always the best option, as it requires that you always use all of the
generated numbers in the same order, even if you only want a subset of the
level's data. This is particularly significant for large levels.

It's sometimes better to use a hierarchy of PRNGs, where the values
generated by higher-level PRNGs are used as seeds for the lower-level
PRNGs. This way, if you need to generate a subset of the data, you only
need to run the PRNGs for the specific subset, and their ancestors.

E.g. if you want a 256x256 grid of random numbers, you could just generate
65536 random numbers and use them in top-to-bottom, left-to-right order.
But if you only want the bottom-right tile, you still need to generate all
of the preceding numbers to ensure that you get the correct value.

A hierarchical approach would generate 4 numbers which are used as the
seeds for the 4 128x128 quarters. Each quarter uses its seed to generate 4
more numbers for the 4 64x64 quarters. And so on until you get down to a
2x2 region, at which point the 4 numbers generated are the actual values
used.

This way, calculating a single cell only requires 4*log(n) (e.g. 4*8=32)
values, while generating the entire grid only requires 33% more numbers
for the higher levels (1 + 1/4 + 1/16 + 1/64 + ... = 1+1/3).

 
Reply With Quote
 
frednotbob@hotmail.ca
Guest
Posts: n/a
 
      11-21-2012
>
>The former can be generated from the seed each
>time you enter the level; the latter must be generated the first time then
>stored.
>


Random.random() is already populating the levelSeed list; I've set it as part of new_game() so that any time the player begins a new game, the levelSeed list is replenished with a new set of data.

The problem, in a nutshell, is this:

When the player starts a new game, make_map() randomly generates level 'Foo' as the player's starting floor. Floor 'Bar' is similarly generated as the player descends from 'Foo' to 'Bar.

Each time the player goes from 'Foo' to 'Bar' (or vice versa), make_map randomly generates a new layout for either level.

What I'd like to do is select values from 'levelSeed' and assign them to the levels that make_map generates so that the player goes back to the same 'Foo' and 'Bar' each time (at least until the player repopulates levelSeed with new values by whatever method I eventually decide to use).

I simply can't find any relevant examples online; everything I've found so far is either intended for a different purpose or assumes that the reader is already an experienced programmer.
 
Reply With Quote
 
frednotbob@hotmail.ca
Guest
Posts: n/a
 
      11-21-2012
>
>The former can be generated from the seed each
>time you enter the level; the latter must be generated the first time then
>stored.
>


Random.random() is already populating the levelSeed list; I've set it as part of new_game() so that any time the player begins a new game, the levelSeed list is replenished with a new set of data.

The problem, in a nutshell, is this:

When the player starts a new game, make_map() randomly generates level 'Foo' as the player's starting floor. Floor 'Bar' is similarly generated as the player descends from 'Foo' to 'Bar.

Each time the player goes from 'Foo' to 'Bar' (or vice versa), make_map randomly generates a new layout for either level.

What I'd like to do is select values from 'levelSeed' and assign them to the levels that make_map generates so that the player goes back to the same 'Foo' and 'Bar' each time (at least until the player repopulates levelSeed with new values by whatever method I eventually decide to use).

I simply can't find any relevant examples online; everything I've found so far is either intended for a different purpose or assumes that the reader is already an experienced programmer.
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      11-21-2012
On Tue, 20 Nov 2012 18:18:17 -0800, frednotbob wrote:


> The problem, in a nutshell, is this:
>
> When the player starts a new game, make_map() randomly generates level
> 'Foo' as the player's starting floor. Floor 'Bar' is similarly
> generated as the player descends from 'Foo' to 'Bar.
>
> Each time the player goes from 'Foo' to 'Bar' (or vice versa), make_map
> randomly generates a new layout for either level.
>
> What I'd like to do is select values from 'levelSeed' and assign them to
> the levels that make_map generates so that the player goes back to the
> same 'Foo' and 'Bar' each time (at least until the player repopulates
> levelSeed with new values by whatever method I eventually decide to
> use).


Just store a mapping between levels and seeds:

levels = {} # starts out blank

Now, each time you enter a level, see if there is a seed recorded, and if
so, use that. Here I assume each level has a name, and you look up by
name.

name = "Lock And Load"
if name in levels:
seed = levels[name]
else:
# Never seen this level before.
seed = pick_a_new_seed_somehow()
levels[name] = seed
map = make_map(name, seed) # whatever arguments needed
redraw(map)



--
Steven
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      11-21-2012
On Wed, Nov 21, 2012 at 1:18 PM, <(E-Mail Removed)> wrote:
> Each time the player goes from 'Foo' to 'Bar' (or vice versa), make_map randomly generates a new layout for either level.
>
> What I'd like to do is select values from 'levelSeed' and assign them to the levels that make_map generates so that the player goes back to the same'Foo' and 'Bar' each time (at least until the player repopulates levelSeedwith new values by whatever method I eventually decide to use).


The easiest way would be to retain a mapping of seeds, eg:

seeds = {'Foo': 142857, 'Bar': 271828}

And then you reseed the random number generator with seeds[level] each
time. (If your levels are identified by consecutive integers starting
from 0 or 1, you could use a list instead of a dictionary, but the
same applies.)

However, this still means that the player will see the exact same
level regenerated every time, absolutely fresh. As previously stated
in this thread, that's not usually a good thing for encounters,
treasure, etc. Once some nasty critter has been killed, he should STAY
killed!

ChrisA
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      11-21-2012
On Wed, 21 Nov 2012 14:41:24 +1100, Chris Angelico wrote:

> However, this still means that the player will see the exact same level
> regenerated every time, absolutely fresh. As previously stated in this
> thread, that's not usually a good thing for encounters, treasure, etc.
> Once some nasty critter has been killed, he should STAY killed!


Why? That isn't true in real life, why should it be true for games?


--
Steven
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      11-21-2012
On Wed, Nov 21, 2012 at 2:47 PM, Steven D'Aprano
<(E-Mail Removed)> wrote:
> On Wed, 21 Nov 2012 14:41:24 +1100, Chris Angelico wrote:
>
>> However, this still means that the player will see the exact same level
>> regenerated every time, absolutely fresh. As previously stated in this
>> thread, that's not usually a good thing for encounters, treasure, etc.
>> Once some nasty critter has been killed, he should STAY killed!

>
> Why? That isn't true in real life, why should it be true for games?


It's either Rule of Fun or Rule of Funny, and I don't really care which...

ChrisA
[1] http://tvtropes.org/pmwiki/pmwiki.php/Main/RuleOfFun
[2] http://tvtropes.org/pmwiki/pmwiki.php/Main/RuleOfFunny
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Issue with seeded map generation Graham Fielding Python 1 12-08-2012 10:53 PM
Re: Issue with seeded map generation Mitya Sirenef Python 0 12-08-2012 10:27 PM
Suggestions for a well seeded torrent to test bittorrent performance? Mark C NZ Computing 1 04-13-2006 12:06 AM
Suggestions for a well seeded torrent to test bittorrent performance? Mark C NZ Computing 0 04-12-2006 11:52 PM
Random numbers seeded with System.currentTimeMillis Roedy Green Java 8 03-09-2006 10:59 PM



Advertisments