'2D dungeon map generation
I'm currently working on a text-based dungeon-crawler game.
My question is: What is the simplest method to make a randomly generated dungeon (say, like the binding of isaac), where there are 4 possible directions to go (north, south, east, west)? Since there are no visuals, I literally just need an object (a level) that is a bunch of these tiles). I also need every tile to connect to at least one other tile.
I've thought about using a center and then randomly generating 1-4 tiles away from the center, then 1-4 tiles from those tiles and so on, but that is highly inefficient since it creates a lot of overlap. I'd also like to decide the number of tiles, and I can't with that.
I'm using python 3. I've created a rudimentary Tile class where it has 4 outgoing variables (n,s,e,w) which can be set to other tiles. I'm stuck there.
Thanks!
Edit. This is what I've done so far, it should work but I don't have any way to test it right now:
from random import randint
class Level(object):
"""Class that represents a level/floor"""
class Tile(object):
"""Class that represents a tile."""
def __init__(self, previousDirection = None, previousTile = None, location = ''):
self.paths = {'n': None, 's': None, 'e': None, 'w': None}
if previousTile != None and previousDirection!=None:
self.paths[Level.Tile.antipath(previousDirection)] = previousTile
self.enemies = [0]*randint(0,10)
self.location = location
def __str__(self):
rep = "Location: {}, ".format(self.location)
rep += "Enemies: "
for enemy in self.enemies:
rep += (str(enemy) + ", ")
rep += 'Paths: '
for path in self.paths:
if self.paths[path]!=None:
rep += (path + ', ')
return rep
def __add__(self, other):
if len(self.enemies)>len(other.enemies):
return self
else:
return other
@staticmethod
def locationparser(location):
directions_l = []
for direction in location:
antidirection = Level.Tile.antipath(direction)
if antidirection in directions_l:
directions_l.remove(antidirection)
else:
directions_l.append(direction)
return "".join(sorted(directions_l))
@staticmethod
def antipath(path):
for pathpair in [['n', 's'], ['e','w']]:
if path in pathpair:
pathpair.remove(path)
return pathpair[0]
raise ValueError('No such path exists')
def __init__(self, stage): #stage will start at 1
self.center_tile = Level.Tile()
self.stage = stage
self.maxdepth = randint(3, int(stage) + 5)
self.tiles = 1
self.locations = []
#number of iterations around center
def r_generate(self, tile, location, depth):
if depth == self.maxdepth:
return
else:
for path in tile.paths:
location_next = Level.Tile.locationparser(location + path)
if tile.paths[path] == None:
if randint(0,1) == 1:
if location_next in self.locations:
existing_tile = Level.find_tile_from_plocation(location_next)
tile.paths[path] = existing_tile
existing_tile.paths[Level.Tile.antipath(path)] = tile
else:
self.locations += location_next
self.tiles += 1 #counting tiles
tile.paths[path] = Level.Tile(path, tile, location_next)
Level.r_generate(self, tile.paths[path], location_next, depth+1)
def find_tile_from_plocation(self, plocation):
"""Finds a tile from the center from a parsed location"""
current_tile = self.center_tile
for direction in plocation:
if current_tile.paths[direction] != None:
current_tile = current_tile.paths[direction]
else:
raise ValueError("There is no tile at that location")
return current_tile
Solution 1:[1]
take a look at thoses, and just choose one
https://en.wikipedia.org/wiki/Maze_generation_algorithm
ps: to have multiple paths available you can modify the algos to let multiple paths open
Solution 2:[2]
I figured it out. The code is under the github repo "true_adventure" from the user super1iminal. It's the file called tiles. I don't want to put it here since it uses other files and blah blah.
-super1iminal
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ren |
Solution 2 | super1iminal |