views:

89

answers:

4

So, I was thinking about making a simple random world generator. This generator would create a starting "cell" that would have between one and four random exits (in the cardinal directions, something like a maze). After deciding those exits, I would generate a new random "cell" at each of those exits, and repeat whenever a player would get near a part of the world that had not yet been generated. This concept would allow a "infinite" world of sorts, all randomly generated; however, I am unsure of how to best represent this internally.

I am using C++ (which doesn't really matter, I could implement any sort of data structure necessary). At first I thought of using a sort of directed graph in which each node would have directed edges to each cell surrounding it, but this probably won't work well if a user finds a spot in the world, backtracks, and comes back to that spot from another direction. The world might do some weird things, such as generate two cells at one location.

Any ideas on what kind of data structure might be the most effective for such a situation? Or am I doing something really dumb with my random world generation?

Any help would be greatly appreciated. Thanks, Chris

+4  A: 

A map< pair<int,int>, cell> would probably work well; the pair would represent the x,y coordinates. If there's not a cell in the map at those coordinates, create a new cell. If you wanted to make it truly infinite, you could replace the ints with an arbitrary length integer class that you would have to provide (such as a bigint)

I can't believe I didn't think of this, its such a simple solution, and fast.
Chris Covert
As @Nathon mentioned for a new cell, be sure to check if adjacent cells exist and create/prevent doors into those adjacent cells as appropriate.
jholl
+1  A: 

Couldn't you have a hash (or STL set) that stored a collection of all grid coordinates that contain occupied cells?

Then when you are looking at creating a new cell, you can quickly check to see if the candidate cell location is already occupied.

(if you had finite space, you could use a 2d array - I think I saw this in a Byte magazine article back in ~1980-ish, but if I understand correctly, you want a world that could extend indefinitely)

winwaed
+2  A: 

If the world's cells are arranged in a grid, you can easily give them cartesian coordinates. If you keep a big list of existing cells, then before determining exits from a given cell, you can check that list to see if any of its neighbors already exist. If they do, and you don't want to have 1-way doors (directed graph?) then you'll have to take their exits into account. If you don't mind having chutes in your game, you can still choose exits randomly, just make sure that you link to existing cells if they're there.

Optimization note: checking a hash table to see if it contains a particular key is O(1).

Nathon
The only issue would be that the lookup times would start to be bad once the world grew, wouldn't they?
Chris Covert
Not if he uses a hash table.
Nathon
Good point about the one-way door and the need for a directed graph.
Brian Stinar
+3  A: 

I recommend you read about graphs. This is exactly an application of random graph generation. Instead of 'cell' and 'exit' you are describing 'node' and 'edge'.

Plus, then you can do things like shortest path analysis, cycle detection and all sorts of other useful graph theory application.

This will help you understand about the nodes and edges:

and here is a finished application of these concepts. I implemented this in a OOP way - each node knew about it's edges to other nodes. A popular alternative is to implement this using an adjacency list. I think the adjacency list concept is basically what user470379 described with his answer. However, his map solution allows for infinite graphs, while a traditional adjacency list does not. I love graph theory, and this is a perfect application of it.

Good luck!

-Brian J. Stianr-

Brian Stinar
I really wanted to use graphs, and maybe I will, I'll have to look around a bit. I just feel a HashMap might be more efficient.
Chris Covert
It just depends on what you want to do, and how you want to approach the problem. If you are talking about something that a human player will interact with, I think the clarity associated with thinking about this as a graph will outweigh any efficiency gains you achieve by using a HashMap. Do you really care if your program takes one second to generate a random graph which is easy to reason about, versus 1/10 of a second to generate a HashMap which is difficult to debug or apply any of the numerous existing algorithms to?
Brian Stinar