Return to Snippet

Revision: 16666
at August 11, 2009 21:39 by goldenratio


Initial Code
import math
import random
import pygame
from random import randint
from GameObjects import Vector

class DungeonGenerator(object):
	
	def __init__(self, rows, cols, num_features, num_specials): # number of rooms too
		def rcell():
			return (randint(0, cols - 1), randint(0, rows - 1))
		def rcellin(rect):
			return ( (randint(rect.x,rect.x+rect.width-1), randint(rect.y,rect.y+rect.height-1)) )
		def cell(pos):
			return self.level[pos[1]][pos[0]]
		def setcell(pos, val):
			self.level[pos[1]][pos[0]] = val
		def feature(pos, size):
			return pygame.Rect(pos[0], pos[1], size, size)
		def canbuild(feature):
			# make sure it's not outside the screen
			if feature.x < 0 or feature.y < 0:
				return False
			if feature.x + feature.width > cols:
				return False
			if feature.y + feature.height > rows:
				return False
			# make sure it doesn't cross another feature
			# for x in range(feature.width):
			# 	for y in range(feature.height):
			# 		if cell((x,y)) == 1:
			# 			return False
			return True
		def build(rect):
			cur = pygame.Rect(rect)
			for x in range(rect.width):
				for y in range(rect.height):
					setcell((cur.x, cur.y), 1) # space
					cur.top += 1
				cur.left += 1
				cur.top = rect.top
		def connect(start, end):
			v = Vector.from_points((start.x, start.y), (end.x, end.y))
			cur = feature((start.x,start.y), 1)
			if random.getrandbits(1) == 0:
				for x in range(int(math.fabs(v.x))): # total number of steps in x direction
					setcell(cur, 1)
					cur.x += 1 if v.x > 0 else -1
				for y in range(int(math.fabs(v.y))):
					setcell(cur, 1)
					cur.y += 1 if v.y > 0 else -1
			else:
				for y in range(int(math.fabs(v.y))):
					setcell(cur, 1)
					cur.y += 1 if v.y > 0 else -1
				for x in range(int(math.fabs(v.x))): # total number of steps in x direction
					setcell(cur, 1)
					cur.x += 1 if v.x > 0 else -1
			
		# create multidimensional array of ints:
			# 0 = cannot walk
			# 1 = can walk
			# 2 = start
			# 3 = exit
			# 4 = item
		zeros = [0] * cols;
		self.level = [zeros[:] for x in range(rows)]
		del zeros
		
		# place "features"
		features = []
		farthest = []
		highest_mag = 0
		for x in range(num_features):
			# pick random feature
			f = feature(rcell(), randint(2, 6))
			# see if we can build it
			while not canbuild(f):
				# if not, pick another random feature
				f = feature(rcell(), randint(2, 6))
			# build it
			build(f)
			# check for farthest features
			for f2 in features:
				# calc magnitude between new feature and all old ones
				mag = Vector.from_points( (f.x, f.y), (f2.x, f2.y) ).magnitude()
				if mag > highest_mag:
					highest_mag = mag
					farthest = [f, f2]
			# append to list of built features
			features.append(f)
			
		# connect "features" together
		last_feature = feature(( features[0].x, features[0].y ), 1)
		for f in features:
			connect(last_feature, f)
			last_feature = feature((f.x,f.y),1)
		del last_feature
		
		# place start and end points
		start, end = farthest[0], farthest[1]
		setcell(rcellin(start), 2)
		setcell(rcellin(end), 3)
		
		# place special points
		for x in range(num_specials):
			f = random.choice(features)
			spec = rcellin(f)
			while cell(spec) != 1: # open space
				f = random.choice(features)
				spec = rcellin(f)
			setcell(spec, 4)
			
		del features

Initial URL


Initial Description


Initial Title
random dungeon generator

Initial Tags


Initial Language
Python