Room now can now generate with a corridor; implemenent door placement finding

This commit is contained in:
Charles Peyrat 2021-01-07 07:06:08 +01:00
parent 9fb366aaab
commit 5579f5d791
1 changed files with 65 additions and 14 deletions

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from enum import auto, Enum from enum import auto, Enum
from random import choice, random, randint from random import choice, random, randint, shuffle
from ..interfaces import Map, Tile from ..interfaces import Map, Tile
@ -12,12 +12,13 @@ DEFAULT_PARAMS = {
"height" : 40, "height" : 40,
"tries" : 600, "tries" : 600,
"max_rooms" : 99, "max_rooms" : 99,
"max_room_tries" : 15,
"cross_room" : 1, "cross_room" : 1,
"corridor" : .8, "corridor_chance" : .8,
"min_v_corridor" : "min_v_corr" : 2,
"max_v_corridor" : "max_v_corr" : 6,
"min_h_corridor" : "min_h_corr" : 4,
"max_h_corridor" : "max_h_corr" : 12,
"large_circular_room" : .10, "large_circular_room" : .10,
"circular_holes" : .5, "circular_holes" : .5,
} }
@ -27,6 +28,49 @@ class Generator:
def __init__(self, params: dict = DEFAULT_PARAMS): def __init__(self, params: dict = DEFAULT_PARAMS):
self.params = params self.params = params
def corr_meta_info(self):
if random() < self.params["corridor_chance"]:
h_sup = randint(self.params["min_h_corr"], \
self.params["max_h_corr"]) if random() < .5 else 0
w_sup = 0 if h_sup else randint(self.params["min_w_corr"], \
self.params["max_w_coor"])
h_off = h_sup if random() < .5 else 0
w_off = w_sup if random() < .5 else 0
return h_sup, w_sup, h_off, w_off
return 0, 0, 0, 0
def attach_door(self, room, h_sup, w_sup, h_off, w_off):
l = h_sup + w_sup
dy, dx = 0, 0
if l > 0:
if h_sup:
dy = -1 if h_off else 1
else:
dx = -1 if w_off else 1
else:
if random() < .5:
dy = -1 if random() < .5 else 1
else:
dx = -1 if random() < .5 else 1
yxs = [i for i in range(len(room) * len(room[0]))]
shuffle(xys)
for POS in yxs:
y, x = POS // len(room), POS % len(room)
if room[y][x] == Tile.EMPTY:
if room[y-dy][x-dx] == Tile.FLOOR:
build_here = True
for i in range(l):
if room[y+i*dy][x+i*dx] != Tile.EMPTY:
build_here = False
break
if build_here:
for i in range(l):
room[y+i*dy][x+i*dx] == Tile.FLOOR
break
return y+l*dy, x+l*dx
def create_circular_room(self): def create_circular_room(self):
if random() < self.params["large_circular_room"]: if random() < self.params["large_circular_room"]:
r = randint(5, 10)**2 r = randint(5, 10)**2
@ -34,18 +78,25 @@ class Generator:
r = randint(2, 4)**2 r = randint(2, 4)**2
room = [] room = []
height = 2*r+2+self.params["max_h_corridor"]
width = 2*r+2+self.params["max_v_corridor"] h_sup, w_sup, h_off, w_off = self.corr_meta_info()
height = 2*r+2
width = 2*r+2
make_hole = random() < self.params["circular_holes"] make_hole = random() < self.params["circular_holes"]
if make_hole: if make_hole:
r2 = randint(3, r-3) r2 = randint(3, r-3)
for i in range(height): for i in range(height+h_sup):
room.append([]) room.append([])
d = (i-height//2)**2 d = (i-h_off-height//2)**2
for j in range(width): for j in range(width+w_sup):
if d + (j-width//2)**2 < r**2 and \ if d + (j-w_off-width//2)**2 < r**2 and \
(not(make_hole) or d + (j-width//2)**2 >= r2**2): (not(make_hole) or d + (j-w_off-width//2)**2 >= r2**2):
room[-1].append(Tile.FLOOR) room[-1].append(Tile.FLOOR)
else: else:
room[-1].append(Tile.EMPTY) room[-1].append(Tile.EMPTY)
return room
door_y, door_x = self.attach_doors(room, h_sup, w_sup, h_off, w_off)
return room, doory, doorx