Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #33562 > unrolled thread
| Started by | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| First post | 2012-11-19 18:31 -0500 |
| Last post | 2012-11-21 03:37 +0000 |
| Articles | 15 — 7 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Getting a seeded value from a list Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-11-19 18:31 -0500
Re: Getting a seeded value from a list frednotbob@hotmail.ca - 2012-11-19 21:45 -0800
Re: Getting a seeded value from a list frednotbob@hotmail.ca - 2012-11-19 21:45 -0800
Re: Getting a seeded value from a list Nobody <nobody@nowhere.com> - 2012-11-20 08:26 +0000
Re: Getting a seeded value from a list frednotbob@hotmail.ca - 2012-11-20 18:18 -0800
Re: Getting a seeded value from a list Chris Angelico <rosuav@gmail.com> - 2012-11-21 14:41 +1100
Re: Getting a seeded value from a list Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-21 03:47 +0000
Re: Getting a seeded value from a list Chris Angelico <rosuav@gmail.com> - 2012-11-21 15:00 +1100
RE: Getting a seeded value from a list "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-23 16:27 +0000
Re: Getting a seeded value from a list Chris Angelico <rosuav@gmail.com> - 2012-11-24 09:32 +1100
RE: Getting a seeded value from a list "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-26 20:17 +0000
Re: Getting a seeded value from a list Hans Mulder <hansmu@xs4all.nl> - 2012-11-27 02:01 +0100
Re: Getting a seeded value from a list Chris Angelico <rosuav@gmail.com> - 2012-11-27 07:24 +1100
Re: Getting a seeded value from a list frednotbob@hotmail.ca - 2012-11-20 18:18 -0800
Re: Getting a seeded value from a list Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-21 03:37 +0000
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2012-11-19 18:31 -0500 |
| Subject | Re: Getting a seeded value from a list |
| Message-ID | <mailman.17.1353367913.29569.python-list@python.org> |
On Sun, 18 Nov 2012 19:00:57 -0800, Graham Fielding
<frednotbob@hotmail.ca> 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
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [next] | [standalone]
| From | frednotbob@hotmail.ca |
|---|---|
| Date | 2012-11-19 21:45 -0800 |
| Message-ID | <d99cec9e-6ace-4c03-b7b8-98a4aa65fa82@googlegroups.com> |
| In reply to | #33562 |
> > 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....
[toc] | [prev] | [next] | [standalone]
| From | frednotbob@hotmail.ca |
|---|---|
| Date | 2012-11-19 21:45 -0800 |
| Message-ID | <mailman.29.1353390359.29569.python-list@python.org> |
| In reply to | #33562 |
> > 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....
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2012-11-20 08:26 +0000 |
| Message-ID | <pan.2012.11.20.08.26.57.630000@nowhere.com> |
| In reply to | #33586 |
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).
[toc] | [prev] | [next] | [standalone]
| From | frednotbob@hotmail.ca |
|---|---|
| Date | 2012-11-20 18:18 -0800 |
| Message-ID | <993b9303-dbca-43f1-9ff4-9677278776b1@googlegroups.com> |
| In reply to | #33562 |
> >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.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-21 14:41 +1100 |
| Message-ID | <mailman.128.1353469287.29569.python-list@python.org> |
| In reply to | #33696 |
On Wed, Nov 21, 2012 at 1:18 PM, <frednotbob@hotmail.ca> 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 levelSeed with 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
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-21 03:47 +0000 |
| Message-ID | <50ac4ee7$0$21790$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #33700 |
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
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-21 15:00 +1100 |
| Message-ID | <mailman.129.1353470428.29569.python-list@python.org> |
| In reply to | #33702 |
On Wed, Nov 21, 2012 at 2:47 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> 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
[toc] | [prev] | [next] | [standalone]
| From | "Prasad, Ramit" <ramit.prasad@jpmorgan.com> |
|---|---|
| Date | 2012-11-23 16:27 +0000 |
| Message-ID | <mailman.233.1353688089.29569.python-list@python.org> |
| In reply to | #33702 |
Steven D'Aprano 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 is not true in all games. I have seen games where treasures regenerate in the same location except for key items. Same goes for enemies (where only "bosses" do not regenerate). It really just depends on the type of game you are playing--designing in this case. ~Ramit This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-24 09:32 +1100 |
| Message-ID | <mailman.245.1353709970.29569.python-list@python.org> |
| In reply to | #33702 |
On Sat, Nov 24, 2012 at 3:27 AM, Prasad, Ramit <ramit.prasad@jpmorgan.com> wrote: > Steven D'Aprano 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 is not true in all games. I have seen games where treasures > regenerate in the same location except for key items. Same goes > for enemies (where only "bosses" do not regenerate). It really > just depends on the type of game you are playing--designing > in this case. Perhaps they regenerate, but do they regenerate from the exact same random seed? For instance, in Murkon's Refuge, the maps are handcrafted and thus constant every time you enter a particular level - but go downstairs and upstairs, and the monsters and treasure regenerate, different from last time. Of course, if the idea is that you're rewinding time, then it makes good sense for you to see the exact same pattern of enemies. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | "Prasad, Ramit" <ramit.prasad@jpmorgan.com> |
|---|---|
| Date | 2012-11-26 20:17 +0000 |
| Message-ID | <mailman.295.1353961077.29569.python-list@python.org> |
| In reply to | #33702 |
Chris Angelico wrote: > > On Sat, Nov 24, 2012 at 3:27 AM, Prasad, Ramit > <ramit.prasad@jpmorgan.com> wrote: > > Steven D'Aprano 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 is not true in all games. I have seen games where treasures > > regenerate in the same location except for key items. Same goes > > for enemies (where only "bosses" do not regenerate). It really > > just depends on the type of game you are playing--designing > > in this case. > > Perhaps they regenerate, but do they regenerate from the exact same > random seed? For instance, in Murkon's Refuge, the maps are > handcrafted and thus constant every time you enter a particular level > - but go downstairs and upstairs, and the monsters and treasure > regenerate, different from last time. > > Of course, if the idea is that you're rewinding time, then it makes > good sense for you to see the exact same pattern of enemies. > Hmm. I guess most of the games where I remember "regenerating" enemies are a bit older. Chrono Trigger had enemies that would regenerate if you left a map screen and came back, but then again it seems more likely that the enemies were hard coded and not "generated" at all. Either that or they [games] are like Diablo/Castlevania where monsters are constantly "generated". I still hold the opinion that the seeding behavior depends on the game. I wonder what Nethack does? ~Ramit This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email.
[toc] | [prev] | [next] | [standalone]
| From | Hans Mulder <hansmu@xs4all.nl> |
|---|---|
| Date | 2012-11-27 02:01 +0100 |
| Message-ID | <50b410d8$0$6904$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #33942 |
On 26/11/12 21:17:40, Prasad, Ramit wrote: > Chris Angelico wrote: >> >> On Sat, Nov 24, 2012 at 3:27 AM, Prasad, Ramit >> <ramit.prasad@jpmorgan.com> wrote: >>> Steven D'Aprano 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 is not true in all games. I have seen games where treasures >>> regenerate in the same location except for key items. Same goes >>> for enemies (where only "bosses" do not regenerate). It really >>> just depends on the type of game you are playing--designing >>> in this case. >> >> Perhaps they regenerate, but do they regenerate from the exact same >> random seed? For instance, in Murkon's Refuge, the maps are >> handcrafted and thus constant every time you enter a particular level >> - but go downstairs and upstairs, and the monsters and treasure >> regenerate, different from last time. >> >> Of course, if the idea is that you're rewinding time, then it makes >> good sense for you to see the exact same pattern of enemies. >> > > Hmm. I guess most of the games where I remember "regenerating" > enemies are a bit older. Chrono Trigger had enemies that > would regenerate if you left a map screen and came back, but > then again it seems more likely that the enemies were hard > coded and not "generated" at all. Either that or they [games] are > like Diablo/Castlevania where monsters are constantly "generated". > > I still hold the opinion that the seeding behavior depends on the > game. I wonder what Nethack does? When you leave a level, Nethack saves it to the hard disk. When you return, the level is reloaded from disk, so monsters and objects appear where they were when you left the level. The map is also saved, so if you had dug an extra corridor on your first visit, it'll be there when you return. The random level generation only happens if you go to a level you haven't visited before in that game (and sometimes not even then). -- HansM
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-27 07:24 +1100 |
| Message-ID | <mailman.296.1353961501.29569.python-list@python.org> |
| In reply to | #33702 |
On Tue, Nov 27, 2012 at 7:17 AM, Prasad, Ramit <ramit.prasad@jpmorgan.com> wrote: > Hmm. I guess most of the games where I remember "regenerating" > enemies are a bit older. Chrono Trigger had enemies that > would regenerate if you left a map screen and came back, but > then again it seems more likely that the enemies were hard > coded and not "generated" at all. Either that or they [games] are > like Diablo/Castlevania where monsters are constantly "generated". > > I still hold the opinion that the seeding behavior depends on the > game. I wonder what Nethack does? I don't know what Nethack does, but I know Angband - I used to maintain my own variant (never got as far as publishing, though). Levels are generated completely fresh on first entry; if you go down to level 2, then down to level 3, then up to level 2, it'll be a *different* level 2. No seeds get saved. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | frednotbob@hotmail.ca |
|---|---|
| Date | 2012-11-20 18:18 -0800 |
| Message-ID | <mailman.127.1353464302.29569.python-list@python.org> |
| In reply to | #33562 |
> >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.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-21 03:37 +0000 |
| Message-ID | <50ac4c65$0$21790$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #33697 |
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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web