rework directions and add graphviz output for BSP

This commit is contained in:
kleph 2018-07-29 19:07:53 +02:00
parent fb06c08d67
commit 4be382798d

View file

@ -12,6 +12,11 @@ TILE_SIZE_Y = 16
MIN_LEAF_SIZE = 8
# UP, DOWN, LEFT, RIGHT
DX = [0, 0, -1, 1]
DY = [-1, 1, 0, 0]
BACKWARD = [1, 0, 3, 2]
class Leaf:
""" Leaf of the BSP """
@ -49,16 +54,18 @@ class Leaf:
if self.width < MIN_LEAF_SIZE * 2: # leaf is too small
return False
split_point = random.randint(MIN_LEAF_SIZE, self.width - MIN_LEAF_SIZE)
self.left_leaf = Leaf(self.x, self.y, split_point, self.height, self.id+1)
self.right_leaf = Leaf(self.x + split_point, self.y, self.width - split_point, self.height, self.id+2)
next_id = self.id + 10 + 2 * (self.id % 10)
self.left_leaf = Leaf(self.x, self.y, split_point, self.height, next_id)
self.right_leaf = Leaf(self.x + split_point, self.y, self.width - split_point, self.height, next_id + 1)
else:
# y
if self.height < MIN_LEAF_SIZE * 2: # leaf is too small
return False
split_point = random.randint(MIN_LEAF_SIZE, self.height - MIN_LEAF_SIZE)
self.left_leaf = Leaf(self.x, self.y, self.width, split_point, self.id+1)
self.right_leaf = Leaf(self.x, self.y + split_point, self.width, self.height - split_point, self.id+2)
next_id = self.id + 10 + 2 * (self.id % 10)
self.left_leaf = Leaf(self.x, self.y, self.width, split_point, next_id)
self.right_leaf = Leaf(self.x, self.y + split_point, self.width, self.height - split_point, next_id + 1)
return True
@ -99,8 +106,8 @@ class Room:
return cx, cy
def is_inside(self, x, y):
if x > self.x and x < self.x + self.width \
and y > self.y and y < self.y + self.height:
if self.x < x < self.x + self.width \
and self.y < y < self.y + self.height:
return True
return False
@ -184,6 +191,8 @@ class Level:
# create rooms from partitions
self.rooms = self.generate_rooms(self.tree[0], self.tilemap, [])
self.generate_graphviz(self.tree[0])
self.generate_tunnels()
def draw_map(self):
@ -211,31 +220,25 @@ class Level:
""" carve tunnels in the space left by the rooms """
#self.carve_tunnel(2, 2)
#self.tilemap[0][0] = self.TILE_ROAD
# start some random carvers
# for i in range(0, 5):
#
# randx = random.randint(0, self.sizex)
# randy = random.randint(0, self.sizey)
# while not self.carvable(randx, randy, -1):
# randx = random.randint(0, self.sizex)
# randy = random.randint(0, self.sizey)
#
# self.carve_tunnel(randx, randy)
for i in range(0, 1):
for y in range(2, self.sizey, 1):
for x in range(2, self.sizex, 1):
#if self.tilemap[x][y] == self.TILE_GROUND:
if self.carvable(x, y, -1):
self.carve_tunnel(x, y)
randx = random.randint(0, self.sizex-1)
randy = random.randint(0, self.sizey-1)
while not self.carvable(randx, randy, -1):
randx = random.randint(0, self.sizex-1)
randy = random.randint(0, self.sizey-1)
self.carve_tunnel(randx, randy)
def carve_tunnel(self, startx, starty):
""" carve a tunnel from (startx, starty) """
print("start tunnel at (" + str(startx) + ", " + str(starty) + ")")
# carve
self.tilemap[startx][starty] = self.TILE_HALLWAY
print("start tunnel at (" + str(startx) + ", " + str(starty) + ")")
# construct direction list
dir_list = [0, 1, 2, 3]
@ -243,84 +246,70 @@ class Level:
# choose random direction
direction = int(random.choice(dir_list))
# print("direction chosen " + str(direction))
newx = startx
newy = starty
if direction == 0 and newy > 0: # up
newy -= 1
elif direction == 1 and newy < self.sizey-1: # down
newy += 1
elif direction == 2 and newx > 0: # left
newx -= 1
elif direction == 3 and newx < self.sizex-1: # right
newx += 1
newx = startx + DX[direction]
newy = starty + DY[direction]
print("will dig (" + str(newx) + ", " + str(newy) + ")")
if self.carvable(newx, newy, direction):
# if self.carvable(newx, newy, -1):
# carve
self.tilemap[newx][newy] = self.TILE_HALLWAY
# TODO: remove backward while reseting directions list?
print("dig (" + str(newx) + ", " + str(newy) + ")")
dir_list = [0, 1, 2, 3]
startx = newx
starty = newy
self.carve_tunnel(newx, newy)
# self.draw_map()
else:
# remove this direction from the list
# print("remove direction " + str(direction))
dir_list.remove(direction)
# print(dir_list)
def carvable(self, x, y, d):
testx = x
testy = y
if x < 0 or x > self.sizex - 1:
return False
if y < 0 or y > self.sizey - 1:
return False
print("trying (" + str(x) + ", " + str(y) + "): " + str(self.tilemap[x][y]))
if self.tilemap[x][y] != self.TILE_GROUND:
return False
# check if in a room
for r in self.rooms:
if r.is_inside(x, y):
return False
if self.tilemap[x][y] == self.TILE_GROUND:
# check all directions
if d == -1:
if x - 1 < 0:
return False
if x + 1 >= self.sizex:
return False
if y - 1 < 0:
return False
if y + 1 >= self.sizey:
return False
# prevent hallway from touching each other
check_dir = [0, 1, 2, 3]
# remove_opposite if we have a direction
if d != -1:
check_dir.remove(BACKWARD[d])
if self.tilemap[x-1][y] != self.TILE_GROUND:
return False
if self.tilemap[x+1][y] != self.TILE_GROUND:
return False
if self.tilemap[x][y-1] != self.TILE_GROUND:
return False
if self.tilemap[x][y+1] != self.TILE_GROUND:
for dir in check_dir:
testx = x + DX[dir]
testy = y + DY[dir]
print("checking: (" + str(x) + ", " + str(y) + ") dir: " + str(dir))
if 0 < testx < self.sizex-1:
if 0 < testy < self.sizey-1:
print("tile: " + str(self.tilemap[testx][testy]))
if self.tilemap[testx][testy] == self.TILE_HALLWAY:
return False
return True
# check specific direction
if d == 0 and y - 1 > 0: # up
testy = y - 1
elif d == 1 and y + 1 < self.sizey-1: # down
testy = y + 1
elif d == 2 and x - 1 > 0: # left
testx = x - 1
elif d == 3 and x + 1 < self.sizex-1: # right
testx = x + 1
# if self.tilemap[testx][testy] == self.TILE_GROUND:
def generate_graphviz(self, leaf):
""" generate a dot file for graphviz representation of rooms tree"""
filename='bsp.dot'
f = open(filename, 'w+t')
f.write("digraph BST {\n")
self.generate_graphviz_sub(leaf, f)
f.write("}")
f.close()
# prevent to carve alongside another hallway
# BUG: backward os already carved, so it never returns true
if self.carvable(testx, testy, -1):
return True
def generate_graphviz_sub(self, leaf, f):
return False
f.write("\n\tl" + str(leaf.id) + " [label = " + str(leaf.id) + "];\n")
if leaf.left_leaf:
f.write("\tl" + str(leaf.id )+ " -> l" + str(leaf.left_leaf.id) + ";\n")
self.generate_graphviz_sub(leaf.left_leaf, f)
if leaf.right_leaf:
f.write("\tl" + str(leaf.id) + " -> l" + str(leaf.right_leaf.id) + ";\n")
self.generate_graphviz_sub(leaf.right_leaf, f)
##