539d5ff4 |
class AutomataEngine(object):
def __init__(self, width=None, height=None, data=None, randomize=True):
if data:
self.data = data
elif randomize:
self.data = [ [ random.choice([0]+[1]*3) for y in range(height)] for x in range(width) ]
else:
self.data = [ [1 for y in range(height)] for x in range(width) ]
self.width = width
self.height = height
def get_rect(self, p1, p2):
x1,y1 = p1
x2,y2 = p2
x1,x2 = min([x1,x2]), max([x1,x2])
y1,y2 = min([y1,y2]), max([y1,y2])
result = [row[y1:y2+1] for row in self.data[x1:x2+1]]
return result
def sum_area(self, p1, p2=None, summator=sum):
rect = p1
if isinstance(p2, int):
x,y = rect
rect = self.get_rect( (x-p2,y-p2), (x+p2,y+p2) )
elif p2 is not None:
rect = self.get_rect(p1,p2)
return summator( summator(row) for row in rect )
def iter_with_coords(self):
for x,row in enumerate(self.data):
for y,cell in enumerate(row):
yield x,y,cell
def munge(self):
tmp_data = copy.deepcopy(self.data)
for x,row in enumerate(self.data):
for y,cell in enumerate(row):
tmp_data[x][y] = self.rule(x,y, cell)
return self.__class__(data=tmp_data)
def iter(self, num):
result = self
for x in range(num):
result = self.munge()
return result
def to_map(self):
data = [[0]*len(self.data[0]) for _ in self.data]
for x,y,cell in self.iter_with_coords():
data[x][y] = Tile(x,y, cell in {1,2}, cell == 1)
return data
class MazeGen(AutomataEngine):
def __init__(self, width=None, height=None, data=None, randomize=True, num_rooms=12, max_width=15, max_height=15, **kw):
kw['randomize'] = False
AutomataEngine.__init__(self, width, height, data, **kw)
points = [ (random.randrange(self.width), random.randrange(self.height))
for _ in range(num_rooms)
]
connections = []
for p in points:
p2 = random.choice(points)
while p == p2:
p2 = random.choice(points)
connections.append( (p,p2) )
for p,p2 in connections:
self.connect_points(p,p2, 9)
self.rooms = []
self.expand_rooms(points, max_width, max_height)
def connect_points(self, p1, p2, steps=4):
x1,y1 = p1
x2,y2 = p2
steps = random.randrange(2, steps+1)
cx, cy = x1,y1
h_steps = random.randrange(1,steps) # always at least one vstep
v_steps = steps - h_steps
while (cx,cy) != (x2,y2):
if h_steps > 0 and random.random() < .5:
dx = int(x2-cx)//(h_steps)
stop = cx+dx
a = min([stop,cx])
b = max([stop,cx])
for x in range(a,b):
self.data[x][cy] = 0
h_steps -= 1
cx = stop
elif v_steps > 0:
dy = int(y2-cy)//(v_steps)
stop = cy+dy
a = min([stop,cy])
b = max([stop,cy])
for y in range(a,b):
self.data[cx][y] = 0
v_steps -= 1
cy = stop
elif cx != x2:
stop = x2
a = min([stop,cx])
b = max([stop,cx])
for x in range(a,b+1):
self.data[x][cy] = 0
elif cy != y2:
stop = y2
a = min([stop,cy])
b = max([stop,cy])
for y in range(a,b+1):
self.data[cx][y] = 0
else:
print 'ouch'
break
def expand_rooms(self, points, max_width, max_height):
for point in points:
left_offset = random.randrange(int(max_width/2))
up_offset = random.randrange(int(max_height/2))
cx, cy = point
lx, ty = cx-left_offset, cy-up_offset
if lx < 0:
max_width += lx
lx = 0
if ty < 0:
max_height += ty
ty = 0
w, h = random.randrange(1,max_width+1), random.randrange(1, max_height+1)
if lx + w >= self.width:
lx -= (lx+w) - self.width
if ty + h >= self.height:
ty -= (ty+h) - self.height
room = Rect(lx,ty, w,h)
success = True
for o_room in self.rooms:
success = not o_room ^ room
if success:
self.rooms.append(room)
def rule(self, x,y, cell):
for room in self.rooms:
if (x,y) in room:
return 0
return cell
def munge(self):
tmp_data = copy.deepcopy(self.data)
for x,row in enumerate(self.data):
for y,cell in enumerate(row):
tmp_data[x][y] = self.rule(x,y, cell)
return AutomataEngine(data=tmp_data)
class Automata1(AutomataEngine):
def rule(self, x,y, cell):
sum = self.sum_area( (x,y), 1 ) - cell
if cell == 0 and sum > 3:
return 0
elif sum > 5:
return 1
elif sum in {2,3}:
return cell
else:
return 0
#elif sum <= 1:
# return 1
#else:
# return cell
class Smoother(AutomataEngine):
def rule(self, x,y, cell):
sum = self.sum_area( (x,y), 1 )
if sum <= 1 and cell == 1:
return 0
if sum == 8 and cell == 0:
return 1
else:
return cell
|
539d5ff4 |
start_room = self.gen.rooms[0]
x,y = start_room.random_point
while self.is_blocked(x,y):
x,y = start_room.random_point
self.map_entrance = x,y
self.place_items(self.gen.rooms[0], item_types, max_num_items)
for r in self.gen.rooms[1:]:
# pass
self.place_objects(r,
monster_types, max_num_monsters,
item_types, max_num_items
)
# for r in range(max_rooms):
# w = random.randrange(min_size, max_size)
# h = random.randrange(min_size, max_size)
# x = random.randrange(0, self.width-w-1)
# y = random.randrange(0, self.height-h-1)
# new_room = Rect(x,y, w,h)
# failed = any(
# new_room ^ other_room for other_room in rooms
# )
# if not failed:
# #self.create_room(new_room)
# (new_x, new_y) = new_room.random_point
#
# if num_rooms == 0:
# x,y = new_room.random_point
# while self.is_blocked(x,y):
# x,y = new_room.random_point
#
# self.map_entrance = x,y
#
# else:
# self.place_objects(new_room,
# monster_types, max_num_monsters,
# item_types, max_num_items
# )
#
# prev_x, prev_y = rooms[-1].center
# #while self.is_blocked(prev_x, prev_y):
# # prev_x, prev_y = rooms[-1].random_point
#
# if random.randrange(0,1) == 1:
# self.create_h_tunnel(prev_x, new_x, prev_y)
# self.create_v_tunnel(new_x, prev_y, new_y)
# else:
# self.create_v_tunnel(new_x, prev_y, new_y)
# self.create_h_tunnel(prev_x, new_x, prev_y)
#
# rooms.append(new_room)
# num_rooms += 1
|