def test_bsp(): """ commented out statements work in libtcod-cffi """ bsp = libtcodpy.bsp_new_with_size(0, 0, 64, 64) repr(bsp) # test __repr__ on leaf libtcodpy.bsp_resize(bsp, 0, 0, 32, 32) assert bsp != None # test getter/setters bsp.x = bsp.x bsp.y = bsp.y bsp.w = bsp.w bsp.h = bsp.h bsp.position = bsp.position bsp.horizontal = bsp.horizontal bsp.level = bsp.level # cover functions on leaf #self.assertFalse(libtcodpy.bsp_left(bsp)) #self.assertFalse(libtcodpy.bsp_right(bsp)) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert libtcodpy.bsp_is_leaf(bsp) assert libtcodpy.bsp_contains(bsp, 1, 1) #self.assertFalse(libtcodpy.bsp_contains(bsp, -1, -1)) #self.assertEqual(libtcodpy.bsp_find_node(bsp, 1, 1), bsp) #self.assertFalse(libtcodpy.bsp_find_node(bsp, -1, -1)) libtcodpy.bsp_split_once(bsp, False, 4) repr(bsp) # test __repr__ with parent libtcodpy.bsp_split_once(bsp, True, 4) repr(bsp) # cover functions on parent assert libtcodpy.bsp_left(bsp) assert libtcodpy.bsp_right(bsp) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert not libtcodpy.bsp_is_leaf(bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_left(bsp)), bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_right(bsp)), bsp) libtcodpy.bsp_split_recursive(bsp, None, 4, 2, 2, 1.0, 1.0) # cover bsp_traverse def traverse(node, user_data): return True libtcodpy.bsp_traverse_pre_order(bsp, traverse) libtcodpy.bsp_traverse_in_order(bsp, traverse) libtcodpy.bsp_traverse_post_order(bsp, traverse) libtcodpy.bsp_traverse_level_order(bsp, traverse) libtcodpy.bsp_traverse_inverted_level_order(bsp, traverse) # test __repr__ on deleted node son = libtcodpy.bsp_left(bsp) libtcodpy.bsp_remove_sons(bsp) repr(son) libtcodpy.bsp_delete(bsp)
def main_gen_level_algorithm(): rnd = 0 level = [[ tile.Tile(blocked=True, explore=True, view=True, char='#', color=color.dark_wall) for i in range(const.MAP_WIDTH) ] for j in range(const.MAP_HEIGHT)] rooms = [make.create_room()] bsp = libtcod.bsp_new_with_size(0, 0, 50, 50) libtcod.bsp_split_recursive(bsp, 0, 2, 5, 5, 1.5, 1.5) fathre = libtcod.bsp_right(bsp) print(fathre.y) """ нач: выбираем правого если его нету есть в списке: нач. иначе: добавляем текущий в список возвращаемся к папе выбираем левого нач. """ return level
def process_node(self, node, rooms): if libtcod.bsp_is_leaf(node): width = random.randint(7, node.w) height = random.randint(7, node.h) x = random.randint(node.x, node.x+node.w-width) y = random.randint(node.y, node.y+node.h-height) rooms.append(Room(x, y, width, height)) else: self.process_node(libtcod.bsp_left(node), rooms) self.process_node(libtcod.bsp_right(node), rooms)
def corridor(self, node): """ | Builds a corridor between the left and right children of the given node. | The corridor is Z-shaped, only horizontally and vertically. | The order of h / v corridors is randomly set (50/50). """ left = self.random_spot_in_node(libtcod.bsp_left(node)) right = self.random_spot_in_node(libtcod.bsp_right(node)) if libtcod.random_get_int(0, 0, 1) == 1: self.create_h_corridor(left[0], right[0], left[1]) self.create_v_corridor(left[1], right[1], right[0]) else: self.create_v_corridor(left[1], right[1], left[0]) self.create_h_corridor(left[0], right[0], right[1])
def bsp_leaf_create_tunnel(node, data): # connect each pair of subdivisions with a tunnel if not libtcod.bsp_is_leaf(node): # center coordinates of left child (left_x, left_y) = room_center(libtcod.bsp_left(node)) # center coordinates of right child (right_x, right_y) = room_center(libtcod.bsp_right(node)) # flip a coin (random number that is either 0 or 1) if libtcod.random_get_int(0, 0, 1) == 1: # first move horizontally, then vertically create_h_tunnel(left_x, right_x, left_y) create_v_tunnel(left_y, right_y, right_x) else: # first move vertically, then horizontally create_v_tunnel(left_y, right_y, left_x) create_h_tunnel(left_x, right_x, right_y) return True
def fill_node(self, node, tunnels=4, room_has_walls=True, min_size=6, random_fill=True): if libtcod.bsp_is_leaf(node): # calculate the room size minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if not room_has_walls: if minx > 1: minx -= 1 if miny > 1: miny -= 1 if maxx == self.map.size.w - 2: maxx -= 1 if maxy == self.map.size.h - 2: maxy -= 1 if random_fill: minx = libtcod.random_get_int(None, minx, maxx - min_size + 1) miny = libtcod.random_get_int(None, miny, maxy - min_size + 1) maxx = libtcod.random_get_int(None, minx + min_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + min_size - 1, maxy) # resize the node to fit the room node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # dig the room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self.map[Pos(x, y)].make_floor() else: # resize the node to fit its sons for i in range(tunnels): left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y self.create_corridor(node, left, right)
def traverseNode(self, node, dat): bsp_random_room = True bsp_min_room_size = 5 if libtcod.bsp_is_leaf(node): # calculate the room size minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if minx > 1: minx -= 1 if miny > 1: miny -= 1 if maxx == self.width - 1: maxx -= 1 if maxy == self.height - 1: maxy -= 1 if bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + bsp_min_room_size - 1, maxy) # resize the node to fit the room node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # dig the room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self.digMap(x, y) else: # resize the node to fit its sons left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y # create a corridor between the two lower nodes if node.horizontal: # vertical corridor if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: # no overlapping zone. we need a Z shaped corridor x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) self.vline_up(x1, y - 1) self.hline(x1, y, x2) self.vline_down(x2, y + 1) else: # straight vertical corridor minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) self.vline_down(x, right.y) self.vline_up(x, right.y - 1) else: # horizontal corridor if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: # no overlapping zone. we need a Z shaped corridor y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) self.hline_left(x - 1, y1) self.vline(x, y1, y2) self.hline_right(x + 1, y2) else: # straight horizontal corridor miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) self.hline_left(right.x - 1, y) self.hline_right(right.x, y) return True # required or the library shits itself
def traverse_node(node, dat): global bsp_rooms #Create rooms if libtcod.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == cfg.MAP_WIDTH - 1: maxx -= 1 if maxy == cfg.MAP_HEIGHT - 1: maxy -= 1 #If it's False the rooms sizes are random, else the rooms are filled to the node's size if cfg.FULL_ROOMS == False: minx = libtcod.random_get_int(None, minx, maxx - cfg.MIN_SIZE + 1) miny = libtcod.random_get_int(None, miny, maxy - cfg.MIN_SIZE + 1) maxx = libtcod.random_get_int(None, minx + cfg.MIN_SIZE - 2, maxx) maxy = libtcod.random_get_int(None, miny + cfg.MIN_SIZE - 2, maxy) node.x = minx node.y = miny node.w = maxx-minx + 1 node.h = maxy-miny + 1 #Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): cfg.map[x][y].blocked = False cfg.map[x][y].block_sight = False #Add center coordinates to the list of rooms bsp_rooms.append(((minx + maxx) / 2, (miny + maxy) / 2)) #Create corridors else: left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y if node.horizontal: if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) vline_up(cfg.map, x1, y - 1) hline(cfg.map, x1, y, x2) vline_down(cfg.map, x2, y + 1) else: minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) # catch out-of-bounds attempts while x > cfg.MAP_WIDTH - 1: x -= 1 vline_down(cfg.map, x, right.y) vline_up(cfg.map, x, right.y - 1) else: if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) hline_left(cfg.map, x - 1, y1) vline(cfg.map, x, y1, y2) hline_right(cfg.map, x + 1, y2) else: miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) # catch out-of-bounds attempts while y > cfg.MAP_HEIGHT - 1: y -= 1 hline_left(cfg.map, right.x - 1, y) hline_right(cfg.map, right.x, y) return True
def traverse_node(node, dat): # create rooms if lib.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == var.MAP_WIDTH - 1: maxx -= 1 if maxy == var.MAP_HEIGHT - 1: maxy -= 1 # if its false, the room sizes are random, else the rooms are filled to the node's size if var.FULL_ROOMS == False: minx = random.randint(minx, maxx - var.MIN_SIZE + 2) miny = random.randint(miny, maxy - var.MIN_SIZE + 2) maxx = random.randint(minx + var.MIN_SIZE - 2, maxx) maxy = random.randint(miny + var.MIN_SIZE - 2, maxy) node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): var.map[x][y].blocked = False var.map[x][y].block_sight = False # add center coordinates to the list of rooms var.bsp_rooms.append(((minx + maxx) / 2, (miny + maxy) / 2)) # create corridors else: left = lib.bsp_left(node) right = lib.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y if node.horizontal: if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: x1 = random.randint(left.x, left.x + left.w - 1) x2 = random.randint(right.x, right.x + right.w - 1) y = random.randint(left.y + left.h, right.y) vline_up(var.map, x1, y - 1) hline(var.map, x1, y, x2) vline_down(var.map, x2, y + 1) else: minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = random.randint(minx, maxx) # catch out of bounds attempts while x > var.MAP_WIDTH - 1: x -= 1 vline_down(var.map, x, right.y) vline_up(var.map, x, right.y - 1) else: if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: y1 = random.randint(left.y, left.y + left.h - 1) y2 = random.randint(right.y, right.y + right.h - 1) x = random.randint(left.x + left.w, right.x) hline_left(var.map, x - 1, y1) vline(var.map, x, y1, y2) hline_right(var.map, x + 1, y2) else: miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = random.randint(miny, maxy) # catch out of bounds attempts while y > var.MAP_HEIGHT - 1: y -= 1 hline_left(var.map, right.x - 1, y) hline_right(var.map, right.x, y) return True
def _traverse_node(self, node, dat): # Create room if libtcod.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == self.map_width - 1: maxx -= 1 if maxy == self.map_height - 1: maxy -= 1 if self.full_rooms is False: minx = libtcod.random_get_int(None, minx, maxx - self.min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - self.min_room_size + 1) maxx = libtcod.random_get_int(None, minx + self.min_room_size - 2, maxx) maxy = libtcod.random_get_int(None, miny + self.min_room_size - 2, maxy) node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self._map[x][y].blocked = False self._map[x][y].block_sight = False self._rooms.append(((minx + maxx) // 2, (miny + maxy) // 2)) self._place_objects(minx, miny, maxx, maxy) # Create corridor else: left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y if node.horizontal: if left.x + left.w - 1 < right.x \ or right.x + right.w - 1 < left.x: x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) self._vline_up(x1, y - 1) self._hline(x1, y, x2) self._vline_down(x2, y + 1) else: minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) self._vline_down(x, right.y) self._vline_up(x, right.y - 1) else: if left.y + left.h - 1 < right.y \ or right.y + right.h - 1 < left.y: y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) self._hline_left(x - 1, y1) self._vline(x, y1, y2) self._hline_right(x + 1, y2) else: miny = max(left.y, right.y) maxy = max(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) self._hline_left(right.x - 1, y) self._hline_right(right.x, y) return True
def traverseNode(self,node,dat): bsp_random_room=True bsp_min_room_size=5 if libtcod.bsp_is_leaf(node): # calculate the room size minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if minx > 1: minx -= 1 if miny > 1: miny -=1 if maxx == self.width - 1: maxx -= 1 if maxy == self.height - 1: maxy -= 1 if bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + bsp_min_room_size - 1, maxy) # resize the node to fit the room node.x = minx node.y = miny node.w = maxx-minx + 1 node.h = maxy-miny + 1 # dig the room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self.digMap(x,y); else: # resize the node to fit its sons left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y # create a corridor between the two lower nodes if node.horizontal: # vertical corridor if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: # no overlapping zone. we need a Z shaped corridor x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) self.vline_up(x1, y - 1) self.hline(x1, y, x2) self.vline_down(x2, y + 1) else: # straight vertical corridor minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) self.vline_down(x, right.y) self.vline_up(x, right.y - 1) else: # horizontal corridor if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: # no overlapping zone. we need a Z shaped corridor y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) self.hline_left(x - 1, y1) self.vline(x, y1, y2) self.hline_right(x + 1, y2) else: # straight horizontal corridor miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) self.hline_left(right.x - 1, y) self.hline_right(right.x, y) return True # required or the library shits itself