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