示例#1
0
class CA_CaveFactory:
    def __init__(self, width, height, initial_open=0.60):
        self.__height = height
        self.__width = width
        self.__area = height * width
        self.__CAmap = []
        self.__rooms = []
        self.__leveldata = {}
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__height/2), int(self.__width/2))
        self.__gen_initial_map(width, height, initial_open)

    # Performs the CA operation, then joins separate rooms.  Returns the map, consisting of a grid of ints.
    def gen_map(self):
        loops = random.randrange(2, 4)
        while loops > 0:
            for r in range(1, self.__height-1):
                for c in range(1, self.__width-1):
                    if not self.__CAmap[c][r].permanent:
                        wall_count = self.__adj_wall_count(r, c)
                        if not self.__CAmap[c][r].blocked:
                            if wall_count > 5:
                                self.__CAmap[c][r].blocked = True
                                self.__CAmap[c][r].block_sight = True
                        elif wall_count < 4:
                            self.__CAmap[c][r].blocked = False
                            self.__CAmap[c][r].block_sight = False

            loops -= 1

        self.__join_rooms()

        return self.__CAmap

    def get_rooms(self):
        return self.__rooms

    def create_room(self, room, layout):
        # go through the tiles in the defined rectangle and construct them according to the layout
        x = room.x1 + 1
        y = room.y1
        for char in layout:
            if char == ".":
                self.__CAmap[x][y].permanent = True
                self.__CAmap[x][y].blocked = False
                self.__CAmap[x][y].block_sight = False
            if char == ",":
                self.__CAmap[x][y].permanent = False
                self.__CAmap[x][y].blocked = False
                self.__CAmap[x][y].block_sight = False
            if char == "X":
                self.__CAmap[x][y].permanent = True
                self.__CAmap[x][y].blocked = True
                self.__CAmap[x][y].block_sight = True
            if char == "x":
                self.__CAmap[x][y].permanent = False
                self.__CAmap[x][y].blocked = True
                self.__CAmap[x][y].block_sight = True
            x += 1
            if char == "\n":
                x = room.x1 + 1
                y += 1

    def create_room_features(self, room, layout):
        # Start with an empty set to put level data in
        leveldata = {}

        # go through the tiles in the defined rectangle and construct them according to the layout
        x = room.x1 + 1
        y = room.y1
        for char in layout:
            element = None
            if char == "=": element = "monastery doorway"
            if char == "b": element = "brazier"
            if element: leveldata.update({(x,y):element})
            x += 1
            if char == "\n":
                x = room.x1 + 1
                y += 1

        return leveldata


    def __set_border(self):
        # make all border squares walls
        # This could be moved to a superclass
        for j in range(0,self.__width-1):
            self.__CAmap[j][0].permanent = True
            self.__CAmap[j][self.__height-1].permanent = True

        for j in range(0,self.__height-1):
            self.__CAmap[0][j].permanent = True
            self.__CAmap[self.__width-1][j].permanent = True


    def __gen_initial_map(self,width,height,initial_open):
        # Create an initial map with random tiles removed, plus rooms and fixtures.
        self.__CAmap = map_init(height,width)

        open_count = int(self.__area * initial_open)
        self.__set_border()

        for r in range(MAX_ROOMS):

            # Pick a random selection from our options.
            roomselection = random.choice(roommaking.templefurniture.keys())
            layoutselection = roommaking.templefurniture[roomselection]

            # Get the width and height
            w, h = roommaking.measurements(layoutselection)

            # Find a spot without going off the edge of the map
            x = random.randrange(0, self.__width - w - 1)
            y = random.randrange(0, self.__height - h - 1)

            # Build rooms as Chambers
            new_room = Chamber(x, y, w, h, 'temple')

            # Check against other rooms to ensure this new room overlaps none of the others
            failed = False
            for other_room in self.__rooms:
                if new_room.intersect(other_room):
                    failed = True
                    break

            if not failed:
                # i.e., no intersections, so paint a room
                self.create_room(new_room, layoutselection)

                # Give it some features
                new_room_features = self.create_room_features(new_room, layoutselection)
                self.__leveldata.update(new_room_features)

                print self.__leveldata
                self.__rooms.append(new_room)

                (new_x, new_y) = new_room.center()  # Previously used for player placement (center of first room)

        tree = bspmaking.Leaf(20,20,20,10)
        tree.branch()
        leaves = tree.gatherleaves()
        for leaf in leaves:
            print "Leaf:", leaf.w, leaf.y

        # Chew out a certain amount of 'noise' for the CA function to work over.
        while open_count > 0:
            rand_r = random.randrange(1,self.__height-1)
            rand_c = random.randrange(1,self.__width-1)

            if self.__CAmap[rand_c][rand_r].blocked and not self.__CAmap[rand_c][rand_r].permanent:
                self.__CAmap[rand_c][rand_r].blocked = False
                self.__CAmap[rand_c][rand_r].block_sight = False
                open_count -= 1

    def __adj_wall_count(self,sr,sc):
    # How many walls are surrounding a tile?
        count = 0

        for r in (-1,0,1):
            for c in (-1,0,1):
                if self.__CAmap[(sc + c)][sr + r].blocked and not(c == 0 and r == 0):
                    count += 1

        return count

    def __join_rooms(self):
        # divide the square into equivalence classes
        for r in range(1,self.__height-1):
            for c in range(1,self.__width-1):
                if not self.__CAmap[c][r].blocked:
                    self.__union_adj_sqr(c,r)

        all_caves = self.__ds.split_sets()

        for cave in all_caves.keys():
            self.__join_points(all_caves[cave][0])

    def __join_points(self,pt1):
        next_pt = pt1

        while 1:
            dir = self.__get_tunnel_dir(pt1,self.center_pt) ### This determines the next point to 'drill' to.  Unfortunately it will still drill through 'permanent' tiles.  How to fix?  We could, possibly, use a pathfinding algorithm to get to work our way to the center point.  That should work but might be overkill.  Let's see how often it happens first while I work on cave building.

            if (dir[0] == 0) or (dir[1] == 0):
                next_pt = (pt1[0] + dir[0],pt1[1] + dir[1])
            else:
                if random.randrange(0,1):
                    next_pt = (pt1[0] + dir[0],pt1[1])
                else:
                    next_pt = (pt1[0],pt1[1] + dir[1])

            if self.__CAmap[next_pt[0]][next_pt[1]].permanent: print "Uh oh, permanent tile at", next_pt[0], next_pt[1]

            if self.__stop_drawing(pt1,next_pt,self.center_pt):
                return

            root1 = self.__ds.find(next_pt)
            root2 = self.__ds.find(pt1)

            if root1 != root2:
                self.__ds.union(root1,root2)

            self.__CAmap[next_pt[0]][next_pt[1]].blocked = False
            self.__CAmap[next_pt[0]][next_pt[1]].block_sight = False
            self.__CAmap[next_pt[0]][next_pt[1]].debug = True          # DEBUG

            pt1 = next_pt

    def __stop_drawing(self,pt,npt,cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and not self.__CAmap[npt[0]][npt[1]].blocked:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self,pt1,pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return (h_dir,v_dir)

    def __union_adj_sqr(self,sr,sc):
        loc = (sr,sc)

        for r in (-1,0):
            for c in (-1,0):
                nloc = (sr+r,sc+c)

                if not self.__CAmap[nloc[0]][nloc[1]].blocked and (r+c != -2):
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1,root2)
示例#2
0
class CA_CaveFactory:
    def __init__(self, length, width, initial_open=0.40):
        self.__length = length
        self.__width = width
        self.__area = length * width
        self.__map = []
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__length / 2), int(self.__width / 2))
        self.__gen_initial_map(initial_open)

    def print_grid(self):
        x = 0
        row = ""

        for r in range(0, self.__length):
            for c in range(0, self.__width):
                if self.__map[r][c] in (WALL, PERM_WALL):
                    print '#',
                else:
                    print '.',

            print

    def gen_map(self):
        for r in range(1, self.__length - 1):
            for c in range(1, self.__width - 1):
                wall_count = self.__adj_wall_count(r, c)

                if self.__map[r][c] == FLOOR:
                    if wall_count > 5:
                        self.__map[r][c] = WALL
                elif wall_count < 4:
                    self.__map[r][c] = FLOOR

        self.__join_rooms()

        return self.__map

    # make all border squares walls
    # This could be moved to a superclass
    def __set_border(self):
        for j in range(0, self.__length):
            self.__map[j][0] = PERM_WALL
            self.__map[j][self.__width - 1] = PERM_WALL

        for j in range(0, self.__width):
            self.__map[0][j] = PERM_WALL
            self.__map[self.__length - 1][j] = PERM_WALL

    def __gen_initial_map(self, initial_open):
        for r in range(0, self.__length):
            row = []
            for c in range(0, self.__width):
                row.append(WALL)
            self.__map.append(row)

        open_count = int(self.__area * initial_open)
        self.__set_border()

        while open_count > 0:
            rand_r = randrange(1, self.__length - 1)
            rand_c = randrange(1, self.__width - 1)

            if self.__map[rand_r][rand_c] == WALL:
                self.__map[rand_r][rand_c] = FLOOR
                open_count -= 1

    def __adj_wall_count(self, sr, sc):
        count = 0

        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self.__map[(sr + r)][sc + c] != FLOOR and not(r == 0 and c == 0):
                    count += 1

        return count

    def __join_rooms(self):
        # divide the square into equivalence classes
        for r in range(1, self.__length - 1):
            for c in range(1, self.__width - 1):
                if self.__map[r][c] == FLOOR:
                    self.__union_adj_sqr(r, c)

        all_caves = self.__ds.split_sets()

        for cave in all_caves.keys():
            self.__join_points(all_caves[cave][0])

    def __join_points(self, pt1):
        next_pt = pt1

        while 1:
            dir = self.__get_tunnel_dir(pt1, self.center_pt)
            move = randrange(0, 3)

            if move == 0:
                next_pt = (pt1[0] + dir[0], pt1[1])
            elif move == 1:
                next_pt = (pt1[0], pt1[1] + dir[1])
            else:
                next_pt = (pt1[0] + dir[0], pt1[1] + dir[1])

            if self.__stop_drawing(pt1, next_pt, self.center_pt):
                return

            root1 = self.__ds.find(next_pt)
            root2 = self.__ds.find(pt1)

            if root1 != root2:
                self.__ds.union(root1, root2)

            self.__map[next_pt[0]][next_pt[1]] = FLOOR

            pt1 = next_pt

    def __stop_drawing(self, pt, npt, cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and self.__map[npt[0]][npt[1]] == FLOOR:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self, pt1, pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return (h_dir, v_dir)

    def __union_adj_sqr(self, sr, sc):
        loc = (sr, sc)

        for r in (-1, 0):
            for c in (-1, 0):
                nloc = (sr + r, sc + c)

                if self.__map[nloc[0]][nloc[1]] == FLOOR:
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1, root2)
示例#3
0
class CA_CaveFactory:
    def __init__(self, length, width, initial_open=0.40):
        self.__length = length
        self.__width = width
        self.__area = length * width
        self.__map = []
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__length / 2), int(self.__width / 2))
        self.__gen_initial_map(initial_open)

    def intialize_frmt_ar(self, ar):

        for r in range(0, self.__length):
            ar.append([])

    def format_grid(self):
        x = 0
        row = ""
        local_ar = []
        self.intialize_frmt_ar(local_ar)

        for r in range(0, len(local_ar)):
            for c in range(0, self.__width):
                if self.__map[r][c] in (WALL, PERM_WALL):
                    local_ar[r].append(1)
                else:
                    local_ar[r].append(0)

        return local_ar

    def gen_map(self):
        for r in range(1, self.__length - 1):
            for c in range(1, self.__width - 1):
                wall_count = self.__adj_wall_count(r, c)

                if self.__map[r][c] == FLOOR:
                    if wall_count > 5:
                        self.__map[r][c] = WALL
                elif wall_count < 4:
                    self.__map[r][c] = FLOOR

        self.__join_rooms()

        return self.__map

    # make all border squares walls
    # This could be moved to a superclass
    def __set_border(self):
        for j in range(0, self.__length):
            self.__map[j][0] = PERM_WALL
            self.__map[j][self.__width - 1] = PERM_WALL

        for j in range(0, self.__width):
            self.__map[0][j] = PERM_WALL
            self.__map[self.__length - 1][j] = PERM_WALL

    def __gen_initial_map(self, initial_open):
        for r in range(0, self.__length):
            row = []
            for c in range(0, self.__width):
                row.append(WALL)
            self.__map.append(row)

        open_count = int(self.__area * initial_open)
        self.__set_border()

        while open_count > 0:
            rand_r = randrange(1, self.__length - 1)
            rand_c = randrange(1, self.__width - 1)

            if self.__map[rand_r][rand_c] == WALL:
                self.__map[rand_r][rand_c] = FLOOR
                open_count -= 1

    def __adj_wall_count(self, sr, sc):
        count = 0

        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self.__map[(sr + r)][sc + c] != FLOOR and not (r == 0
                                                                  and c == 0):
                    count += 1

        return count

    def __join_rooms(self):
        # divide the square into equivalence classes
        for r in range(1, self.__length - 1):
            for c in range(1, self.__width - 1):
                if self.__map[r][c] == FLOOR:
                    self.__union_adj_sqr(r, c)

        all_caves = self.__ds.split_sets()

        for cave in all_caves.keys():
            self.__join_points(all_caves[cave][0])

    def __join_points(self, pt1):
        next_pt = pt1

        while 1:
            dir = self.__get_tunnel_dir(pt1, self.center_pt)
            move = randrange(0, 3)

            if move == 0:
                next_pt = (pt1[0] + dir[0], pt1[1])
            elif move == 1:
                next_pt = (pt1[0], pt1[1] + dir[1])
            else:
                next_pt = (pt1[0] + dir[0], pt1[1] + dir[1])

            if self.__stop_drawing(pt1, next_pt, self.center_pt):
                return

            root1 = self.__ds.find(next_pt)
            root2 = self.__ds.find(pt1)

            if root1 != root2:
                self.__ds.union(root1, root2)

            self.__map[next_pt[0]][next_pt[1]] = FLOOR

            pt1 = next_pt

    def __stop_drawing(self, pt, npt, cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and self.__map[npt[0]][
                npt[1]] == FLOOR:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self, pt1, pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return (h_dir, v_dir)

    def __union_adj_sqr(self, sr, sc):
        loc = (sr, sc)

        for r in (-1, 0):
            for c in (-1, 0):
                nloc = (sr + r, sc + c)

                if self.__map[nloc[0]][nloc[1]] == FLOOR:
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1, root2)
示例#4
0
class CA_CaveFactory:
    def __init__(self, width, height, initial_open=0.60):
        self.__height = height
        self.__width = width
        self.__area = height * width
        self.__CAmap = []
        self.__rooms = []
        self.__leveldata = {}
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__height / 2), int(self.__width / 2))
        self.__gen_initial_map(width, height, initial_open)

    # Performs the CA operation, then joins separate rooms.  Returns the map, consisting of a grid of ints.
    def gen_map(self):
        loops = random.randrange(2, 4)
        while loops > 0:
            for r in range(1, self.__height - 1):
                for c in range(1, self.__width - 1):
                    if not self.__CAmap[c][r].permanent:
                        wall_count = self.__adj_wall_count(r, c)
                        if not self.__CAmap[c][r].blocked:
                            if wall_count > 5:
                                self.__CAmap[c][r].blocked = True
                                self.__CAmap[c][r].block_sight = True
                        elif wall_count < 4:
                            self.__CAmap[c][r].blocked = False
                            self.__CAmap[c][r].block_sight = False

            loops -= 1

        self.__join_rooms()

        return self.__CAmap

    def get_rooms(self):
        return self.__rooms

    def create_room(self, room, layout):
        # go through the tiles in the defined rectangle and construct them according to the layout
        x = room.x1 + 1
        y = room.y1
        for char in layout:
            if char == ".":
                self.__CAmap[x][y].permanent = True
                self.__CAmap[x][y].blocked = False
                self.__CAmap[x][y].block_sight = False
            if char == ",":
                self.__CAmap[x][y].permanent = False
                self.__CAmap[x][y].blocked = False
                self.__CAmap[x][y].block_sight = False
            if char == "X":
                self.__CAmap[x][y].permanent = True
                self.__CAmap[x][y].blocked = True
                self.__CAmap[x][y].block_sight = True
            if char == "x":
                self.__CAmap[x][y].permanent = False
                self.__CAmap[x][y].blocked = True
                self.__CAmap[x][y].block_sight = True
            x += 1
            if char == "\n":
                x = room.x1 + 1
                y += 1

    def create_room_features(self, room, layout):
        # Start with an empty set to put level data in
        leveldata = {}

        # go through the tiles in the defined rectangle and construct them according to the layout
        x = room.x1 + 1
        y = room.y1
        for char in layout:
            element = None
            if char == "=": element = "monastery doorway"
            if char == "b": element = "brazier"
            if element: leveldata.update({(x, y): element})
            x += 1
            if char == "\n":
                x = room.x1 + 1
                y += 1

        return leveldata

    def __set_border(self):
        # make all border squares walls
        # This could be moved to a superclass
        for j in range(0, self.__width - 1):
            self.__CAmap[j][0].permanent = True
            self.__CAmap[j][self.__height - 1].permanent = True

        for j in range(0, self.__height - 1):
            self.__CAmap[0][j].permanent = True
            self.__CAmap[self.__width - 1][j].permanent = True

    def __gen_initial_map(self, width, height, initial_open):
        # Create an initial map with random tiles removed, plus rooms and fixtures.
        self.__CAmap = map_init(height, width)

        open_count = int(self.__area * initial_open)
        self.__set_border()

        for r in range(MAX_ROOMS):

            # Pick a random selection from our options.
            roomselection = random.choice(roommaking.templefurniture.keys())
            layoutselection = roommaking.templefurniture[roomselection]

            # Get the width and height
            w, h = roommaking.measurements(layoutselection)

            # Find a spot without going off the edge of the map
            x = random.randrange(0, self.__width - w - 1)
            y = random.randrange(0, self.__height - h - 1)

            # Build rooms as Chambers
            new_room = Chamber(x, y, w, h, 'temple')

            # Check against other rooms to ensure this new room overlaps none of the others
            failed = False
            for other_room in self.__rooms:
                if new_room.intersect(other_room):
                    failed = True
                    break

            if not failed:
                # i.e., no intersections, so paint a room
                self.create_room(new_room, layoutselection)

                # Give it some features
                new_room_features = self.create_room_features(
                    new_room, layoutselection)
                self.__leveldata.update(new_room_features)

                print self.__leveldata
                self.__rooms.append(new_room)

                (new_x, new_y) = new_room.center(
                )  # Previously used for player placement (center of first room)

        tree = bspmaking.Leaf(20, 20, 20, 10)
        tree.branch()
        leaves = tree.gatherleaves()
        for leaf in leaves:
            print "Leaf:", leaf.w, leaf.y

        # Chew out a certain amount of 'noise' for the CA function to work over.
        while open_count > 0:
            rand_r = random.randrange(1, self.__height - 1)
            rand_c = random.randrange(1, self.__width - 1)

            if self.__CAmap[rand_c][rand_r].blocked and not self.__CAmap[
                    rand_c][rand_r].permanent:
                self.__CAmap[rand_c][rand_r].blocked = False
                self.__CAmap[rand_c][rand_r].block_sight = False
                open_count -= 1

    def __adj_wall_count(self, sr, sc):
        # How many walls are surrounding a tile?
        count = 0

        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self.__CAmap[(sc + c)][sr + r].blocked and not (c == 0
                                                                   and r == 0):
                    count += 1

        return count

    def __join_rooms(self):
        # divide the square into equivalence classes
        for r in range(1, self.__height - 1):
            for c in range(1, self.__width - 1):
                if not self.__CAmap[c][r].blocked:
                    self.__union_adj_sqr(c, r)

        all_caves = self.__ds.split_sets()

        for cave in all_caves.keys():
            self.__join_points(all_caves[cave][0])

    def __join_points(self, pt1):
        next_pt = pt1

        while 1:
            dir = self.__get_tunnel_dir(
                pt1, self.center_pt
            )  ### This determines the next point to 'drill' to.  Unfortunately it will still drill through 'permanent' tiles.  How to fix?  We could, possibly, use a pathfinding algorithm to get to work our way to the center point.  That should work but might be overkill.  Let's see how often it happens first while I work on cave building.

            if (dir[0] == 0) or (dir[1] == 0):
                next_pt = (pt1[0] + dir[0], pt1[1] + dir[1])
            else:
                if random.randrange(0, 1):
                    next_pt = (pt1[0] + dir[0], pt1[1])
                else:
                    next_pt = (pt1[0], pt1[1] + dir[1])

            if self.__CAmap[next_pt[0]][next_pt[1]].permanent:
                print "Uh oh, permanent tile at", next_pt[0], next_pt[1]

            if self.__stop_drawing(pt1, next_pt, self.center_pt):
                return

            root1 = self.__ds.find(next_pt)
            root2 = self.__ds.find(pt1)

            if root1 != root2:
                self.__ds.union(root1, root2)

            self.__CAmap[next_pt[0]][next_pt[1]].blocked = False
            self.__CAmap[next_pt[0]][next_pt[1]].block_sight = False
            self.__CAmap[next_pt[0]][next_pt[1]].debug = True  # DEBUG

            pt1 = next_pt

    def __stop_drawing(self, pt, npt, cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and not self.__CAmap[
                npt[0]][npt[1]].blocked:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self, pt1, pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return (h_dir, v_dir)

    def __union_adj_sqr(self, sr, sc):
        loc = (sr, sc)

        for r in (-1, 0):
            for c in (-1, 0):
                nloc = (sr + r, sc + c)

                if not self.__CAmap[nloc[0]][nloc[1]].blocked and (r + c !=
                                                                   -2):
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1, root2)
示例#5
0
class FullMap:
    # A map using CA to build caves but also pre-set rooms.
    def __init__(self, width, height, levelnum, initial_open=0.60):
        self.__height = height
        self.__width = width
        self.__area = height * width
        self.__map = []
        self.__levelnum = levelnum
        self.__rooms = []
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__height / 2), int(self.__width / 2))
        self.objects = []
        self.eventdict = {}
        self.gen_map(initial_open)

    def gen_map(self, initial_open):
        # Create an initial map
        self.__map = map_init(self.__height, self.__width)

        # make all border squares walls
        for j in range(0, self.__width - 1):
            self.__map[j][0].permanent = True
            self.__map[j][self.__height - 1].permanent = True

        for j in range(0, self.__height - 1):
            self.__map[0][j].permanent = True
            self.__map[self.__width - 1][j].permanent = True

        # Chew out randomized spots on the map
        self.randomize(initial_open)

        # Make a list of level features to make
        levellist = levelmaking.choose_levelset(self.__levelnum)

        # Init a counter for events
        currentevent = 1

        # For each item, get the features to make a Chamber out of.  Make a chamber and dig a proper room out of it.
        for item in levellist:
            # Select an item from the possible ones, given the type.
            itemselection = levelmaking.select_elements(item)

            # Want to look until a placement is found.
            placed = False
            while not placed:

                # Given this item, what arguments do we need to actually make the room?
                args = levelmaking.set_element_values(item, itemselection,
                                                      self.__width,
                                                      self.__height)
                new_room = Chamber(*args)

                # Check against other rooms to ensure this new room overlaps none of the others
                # This needs to go somewhere else!
                intersected = False
                for other_room in self.__rooms:
                    if new_room.intersect(other_room):
                        intersected = True
                        print "Failed intersection test!"
                        break

                # In cases of intersection, note the failure, and try again (another loop).  Otherwise, perform the
                # dig-a-room operations and make a note to finish the loop.
                if intersected:
                    print "Failed making", new_room.style
                else:
                    # i.e., no intersections, so paint a room
                    levelmaking.dig_room(self.__map, new_room, itemselection)
                    roomobjects = levelmaking.collect_features(
                        self.__map, new_room, itemselection)
                    self.objects += roomobjects
                    print "Successfully dug", new_room.style
                    self.__rooms.append(new_room)
                    placed = True

                    (new_x, new_y) = new_room.center(
                    )  # Previously used for player placement (center of first room)

        # Perform CA operation - how many loops to perform?
        loops = random.randrange(4, 5)
        self.ca_operation(loops)

        # Check for other room-making operations

        # Join the areas of the level
        self.__join_rooms()

    def finalize_map(self):
        return self.__map

    def finalize_obects(self):
        return self.objects

    def get_rooms(self):
        return self.__rooms

    def is_map_blocked(self, x, y):
        if self.__map[x][y].is_blocked:
            return True
        else:
            return False

    def randomize(self, initial_open):
        open_count = int(self.__width * self.__height * initial_open)
        while open_count > 0:
            rand_r = random.randrange(1, self.__height - 1)
            rand_c = random.randrange(1, self.__width - 1)

            if self.__map[rand_c][rand_r].blocked and not self.__map[rand_c][
                    rand_r].permanent:
                self.__map[rand_c][rand_r].blocked = False
                self.__map[rand_c][rand_r].block_sight = False
                open_count -= 1

    def check_open(self):
        count = 0
        for x in range(1, self.__width):
            for y in range(1, self.__height):
                if self.__map[x][y].blocked:
                    count += 1
        print 'open tiles: ', count

    def ca_operation(self, loops):
        # For non-permanent tiles, grow or kill depending on their surroundings.
        while loops > 0:
            for r in range(1, self.__height - 1):
                for c in range(1, self.__width - 1):
                    if not self.__map[c][r].permanent:
                        wall_count = self.__adj_wall_count(r, c)
                        if not self.__map[c][r].blocked:
                            if wall_count > 5:
                                self.__map[c][r].blocked = True
                                self.__map[c][r].block_sight = True
                        elif wall_count < 4:
                            self.__map[c][r].blocked = False
                            self.__map[c][r].block_sight = False
            loops -= 1

    def __adj_wall_count(self, sr, sc):
        # How many walls are surrounding a tile?
        count = 0

        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self.__map[(sc + c)][sr +
                                        r].blocked and not (c == 0 and r == 0):
                    count += 1

        return count

    def __join_rooms(self):

        all_caves = self.__determine_areas()

        # Build a tunneling map for pathing - use the permanent state check to determine passability.
        tunnelingmap = libtcod.map_new(self.__width, self.__height)
        for x in range(1, self.__width - 1):
            for y in range(1, self.__height - 1):
                perm_wall = (self.__map[x][y].permanent
                             and self.__map[x][y].blocked)
                libtcod.map_set_properties(tunnelingmap, x, y, True,
                                           not perm_wall)

        # The tunneling path will let us move from the origin to the center.
        tunnelingpath = libtcod.dijkstra_new(tunnelingmap, 0.0)

        # The center needs to be non-permanent, otherwise we can't path to it.
        center_x, center_y = self.__find_good_center(self.center_pt)

        for cave in all_caves.keys():
            # This comment used to run the joining.  The function is still usable!
            #self.__join_points(all_caves[cave][0])
            origin_x = all_caves[cave][0][0]
            origin_y = all_caves[cave][0][1]

            libtcod.dijkstra_compute(tunnelingpath, origin_x, origin_y)
            if not libtcod.dijkstra_path_set(tunnelingpath, center_x,
                                             center_y):
                print "Could not path! Center point permanent:", self.__map[
                    center_x][center_y].permanent
            prev_pt = (origin_x, origin_y)
            while not libtcod.dijkstra_is_empty(tunnelingpath):
                x, y = libtcod.dijkstra_path_walk(tunnelingpath)
                next_pt = (x, y)
                if x is not None:

                    root1 = self.__ds.find(next_pt)
                    root2 = self.__ds.find(prev_pt)

                    if root1 != root2:
                        self.__ds.union(root1, root2)

                    self.__map[next_pt[0]][next_pt[1]].blocked = False
                    self.__map[next_pt[0]][next_pt[1]].block_sight = False
                    self.__map[next_pt[0]][next_pt[1]].debug = True  # DEBUG

                    if self.__stop_drawing(prev_pt, next_pt, self.center_pt):
                        print "Done cave", cave
                        break

                    prev_pt = next_pt

        all_caves = self.__determine_areas()
        if len(all_caves.keys()) > 1:
            self.__join_rooms()

    def __determine_areas(self):
        # divide the square into equivalence classes
        for r in range(1, self.__height - 1):
            for c in range(1, self.__width - 1):
                if not self.__map[c][r].blocked:
                    self.__union_adj_sqr(c, r)

        # Get a list of areas to work on, then remove small caves before returning
        areas = self.__ds.split_sets()
        zones = areas.keys()
        for zone in zones:
            if len(areas[zone]) < 9:
                for location in areas[zone]:
                    x = location[0]
                    y = location[1]
                    self.__map[x][y].permanent = False
                    self.__map[x][y].blocked = True
                    self.__map[x][y].block_sight = True
                areas.pop(zone)

        print "Number of areas is", len(areas)
        return areas

    def __find_good_center(self, pt):
        # This function randomly moves the center to find a good 'end' point for cave joining function.
        # That is, the center can't be permanent.
        x = pt[0]
        y = pt[1]
        while self.__map[x][y].permanent:
            x += random.randrange(-1, 1)
            y += random.randrange(-1, 1)
        pt = (x, y)
        return pt

    def __stop_drawing(self, pt, npt, cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and not self.__map[
                npt[0]][npt[1]].blocked:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self, pt1, pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return h_dir, v_dir

    def __union_adj_sqr(self, sr, sc):
        loc = (sr, sc)

        for r in (-1, 0):
            for c in (-1, 0):
                nloc = (sr + r, sc + c)

                if not self.__map[nloc[0]][nloc[1]].blocked and (r + c != -2):
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1, root2)
示例#6
0
class FullMap:
    # A map using CA to build caves but also pre-set rooms.
    def __init__(self, width, height, levelnum, initial_open=0.60):
        self.__height = height
        self.__width = width
        self.__area = height * width
        self.__map = []
        self.__levelnum = levelnum
        self.__rooms = []
        self.__ds = DisjointSet()
        self.__up_loc = 0
        self.center_pt = (int(self.__height/2), int(self.__width/2))
        self.objects = []
        self.eventdict = {}
        self.gen_map(initial_open)

    def gen_map(self, initial_open):
        # Create an initial map
        self.__map = map_init(self.__height, self.__width)

        # make all border squares walls
        for j in range(0, self.__width-1):
            self.__map[j][0].permanent = True
            self.__map[j][self.__height-1].permanent = True

        for j in range(0, self.__height-1):
            self.__map[0][j].permanent = True
            self.__map[self.__width-1][j].permanent = True

        # Chew out randomized spots on the map
        self.randomize(initial_open)

        # Make a list of level features to make
        levellist = levelmaking.choose_levelset(self.__levelnum)

        # Init a counter for events
        currentevent = 1

        # For each item, get the features to make a Chamber out of.  Make a chamber and dig a proper room out of it.
        for item in levellist:
            # Select an item from the possible ones, given the type.
            itemselection = levelmaking.select_elements(item)

            # Want to look until a placement is found.
            placed = False
            while not placed:

                # Given this item, what arguments do we need to actually make the room?
                args = levelmaking.set_element_values(item, itemselection, self.__width, self.__height)
                new_room = Chamber(*args)

                # Check against other rooms to ensure this new room overlaps none of the others
                # This needs to go somewhere else!
                intersected = False
                for other_room in self.__rooms:
                    if new_room.intersect(other_room):
                        intersected = True
                        print "Failed intersection test!"
                        break

                # In cases of intersection, note the failure, and try again (another loop).  Otherwise, perform the
                # dig-a-room operations and make a note to finish the loop.
                if intersected:
                    print "Failed making", new_room.style
                else:
                    # i.e., no intersections, so paint a room
                    levelmaking.dig_room(self.__map, new_room, itemselection)
                    roomobjects = levelmaking.collect_features(self.__map, new_room, itemselection)
                    self.objects += roomobjects
                    print "Successfully dug", new_room.style
                    self.__rooms.append(new_room)
                    placed = True

                    (new_x, new_y) = new_room.center()  # Previously used for player placement (center of first room)

        # Perform CA operation - how many loops to perform?
        loops = random.randrange(4, 5)
        self.ca_operation(loops)

        # Check for other room-making operations


        # Join the areas of the level
        self.__join_rooms()

    def finalize_map(self):
        return self.__map

    def finalize_obects(self):
        return self.objects

    def get_rooms(self):
        return self.__rooms

    def is_map_blocked(self, x, y):
        if self.__map[x][y].is_blocked:
            return True
        else:
            return False

    def randomize(self, initial_open):
        open_count = int(self.__width * self.__height * initial_open)
        while open_count > 0:
            rand_r = random.randrange(1, self.__height-1)
            rand_c = random.randrange(1, self.__width-1)

            if self.__map[rand_c][rand_r].blocked and not self.__map[rand_c][rand_r].permanent:
                self.__map[rand_c][rand_r].blocked = False
                self.__map[rand_c][rand_r].block_sight = False
                open_count -= 1

    def check_open(self):
        count = 0
        for x in range(1, self.__width):
            for y in range(1, self.__height):
                if self.__map[x][y].blocked:
                    count += 1
        print 'open tiles: ', count


    def ca_operation(self, loops):
    # For non-permanent tiles, grow or kill depending on their surroundings.
        while loops > 0:
            for r in range(1, self.__height-1):
                for c in range(1, self.__width-1):
                    if not self.__map[c][r].permanent:
                        wall_count = self.__adj_wall_count(r, c)
                        if not self.__map[c][r].blocked:
                            if wall_count > 5:
                                self.__map[c][r].blocked = True
                                self.__map[c][r].block_sight = True
                        elif wall_count < 4:
                            self.__map[c][r].blocked = False
                            self.__map[c][r].block_sight = False
            loops -= 1

    def __adj_wall_count(self, sr, sc):
    # How many walls are surrounding a tile?
        count = 0

        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self.__map[(sc + c)][sr + r].blocked and not(c == 0 and r == 0):
                    count += 1

        return count

    def __join_rooms(self):

        all_caves = self.__determine_areas()


        # Build a tunneling map for pathing - use the permanent state check to determine passability.
        tunnelingmap = libtcod.map_new(self.__width, self.__height)
        for x in range(1, self.__width-1):
            for y in range(1, self.__height-1):
                perm_wall = (self.__map[x][y].permanent and self.__map[x][y].blocked)
                libtcod.map_set_properties(tunnelingmap, x, y, True, not perm_wall)

        # The tunneling path will let us move from the origin to the center.
        tunnelingpath = libtcod.dijkstra_new(tunnelingmap, 0.0)

        # The center needs to be non-permanent, otherwise we can't path to it.
        center_x, center_y = self.__find_good_center(self.center_pt)

        for cave in all_caves.keys():
            # This comment used to run the joining.  The function is still usable!
            #self.__join_points(all_caves[cave][0])
            origin_x = all_caves[cave][0][0]
            origin_y = all_caves[cave][0][1]

            libtcod.dijkstra_compute(tunnelingpath, origin_x, origin_y)
            if not libtcod.dijkstra_path_set(tunnelingpath, center_x, center_y):
                print "Could not path! Center point permanent:", self.__map[center_x][center_y].permanent
            prev_pt = (origin_x, origin_y)
            while not libtcod.dijkstra_is_empty(tunnelingpath):
                x, y = libtcod.dijkstra_path_walk(tunnelingpath)
                next_pt = (x, y)
                if x is not None:

                    root1 = self.__ds.find(next_pt)
                    root2 = self.__ds.find(prev_pt)

                    if root1 != root2:
                        self.__ds.union(root1, root2)

                    self.__map[next_pt[0]][next_pt[1]].blocked = False
                    self.__map[next_pt[0]][next_pt[1]].block_sight = False
                    self.__map[next_pt[0]][next_pt[1]].debug = True          # DEBUG

                    if self.__stop_drawing(prev_pt, next_pt, self.center_pt):
                        print "Done cave", cave
                        break

                    prev_pt = next_pt

        all_caves = self.__determine_areas()
        if len(all_caves.keys())>1:
            self.__join_rooms()


    def __determine_areas(self):
        # divide the square into equivalence classes
        for r in range(1, self.__height-1):
            for c in range(1, self.__width-1):
                if not self.__map[c][r].blocked:
                    self.__union_adj_sqr(c, r)

        # Get a list of areas to work on, then remove small caves before returning
        areas = self.__ds.split_sets()
        zones = areas.keys()
        for zone in zones:
            if len(areas[zone])<9:
                for location in areas[zone]:
                    x = location[0]
                    y = location[1]
                    self.__map[x][y].permanent = False
                    self.__map[x][y].blocked = True
                    self.__map[x][y].block_sight = True
                areas.pop(zone)

        print "Number of areas is", len(areas)
        return areas

    def __find_good_center(self, pt):
        # This function randomly moves the center to find a good 'end' point for cave joining function.
        # That is, the center can't be permanent.
        x = pt[0]
        y = pt[1]
        while self.__map[x][y].permanent:
            x += random.randrange(-1, 1)
            y += random.randrange(-1, 1)
        pt = (x, y)
        return pt

    def __stop_drawing(self, pt, npt, cpt):
        if self.__ds.find(npt) == self.__ds.find(cpt):
            return 1
        if self.__ds.find(pt) != self.__ds.find(npt) and not self.__map[npt[0]][npt[1]].blocked:
            return 1
        else:
            return 0

    def __get_tunnel_dir(self, pt1, pt2):
        if pt1[0] < pt2[0]:
            h_dir = +1
        elif pt1[0] > pt2[0]:
            h_dir = -1
        else:
            h_dir = 0

        if pt1[1] < pt2[1]:
            v_dir = +1
        elif pt1[1] > pt2[1]:
            v_dir = -1
        else:
            v_dir = 0

        return h_dir, v_dir

    def __union_adj_sqr(self, sr, sc):
        loc = (sr, sc)

        for r in (-1, 0):
            for c in (-1, 0):
                nloc = (sr+r, sc+c)

                if not self.__map[nloc[0]][nloc[1]].blocked and (r+c != -2):
                    root1 = self.__ds.find(loc)
                    root2 = self.__ds.find(nloc)

                    if root1 != root2:
                        self.__ds.union(root1, root2)