Ejemplo n.º 1
0
 def __generate_map(self):
     _maze = Maze(self.lvl_length, self.lvl_width)
     self.map = _maze.gen_map()
     self.lvl_length = _maze.length
     self.lvl_width = _maze.width
     
     # Add a few open spaces
     _tf = TerrainFactory()
     for j in range(randrange(1,4)):
         _row = randrange(4, self.lvl_length - 4)
         _col = randrange(4, self.lvl_width - 4)
         for _r in (-1, 0, 1):
             for _c in (-1, 0 , 1):
                 self.map[_row + _r][_col + _c] = _tf.get_terrain_tile(CYBERSPACE_FLOOR)
Ejemplo n.º 2
0
 def attempt_to_hack_trap(self, player, tile, row, col):
     _hack = player.skills.get_skill("Hacking").get_rank() + 1
     _roll = do_d10_roll(_hack, 0) + player.get_intuition_bonus()
     
     if _roll < 3:
         _msg = 'You set off ' + tile.get_name() + '!'
         self.dm.alert_player(player.row, player.col, _msg)
         raise TrapSetOff()
     elif _roll > 15:
         _tf = TerrainFactory()
         self.map[row][col] = _tf.get_terrain_tile(CYBERSPACE_FLOOR)
         _msg = "You delete " + tile.get_name() + "."
         self.dm.alert_player(player.row, player.col, _msg)
     else:
         _msg = "You aren't able to alter the code fabric."
         self.dm.alert_player(player.row, player.col, _msg)
Ejemplo n.º 3
0
 def generate_map(self):
     self.tf = TerrainFactory()
     
     _map = []
     
     # initialize map
     _ca = CA_CaveFactory(self.lvl_length, self.lvl_width - 10, 0.45)
     _cave = _ca.gen_map([False,False])
     
     for _row in _cave:
         _line = [self.tf.get_terrain_tile(PERM_WALL)]
         _line += [self.tf.get_terrain_tile(PERM_WALL) for j in range(4)]
         _line += _row
         _line += [self.tf.get_terrain_tile(PERM_WALL) for j in range(4)]
         _line.append(self.tf.get_terrain_tile(PERM_WALL))
         _map.append(_line)
     
     self.map = _map
     
     # clear out middle section of map
     for _row in range(8, self.lvl_length - 9):
         for _col in range(7, self.lvl_width - 10):
             self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
             
     # Now draw the tunnel entrance tunnel
     self.draw_entrance_tunnel()
     if self.level_num == 13:
         self.draw_exit_tunnel()
     self.add_buildings()
     self.add_toxic_pools()
Ejemplo n.º 4
0
 def __init__(self,length,width,initial_open=0.40):
     self.__length = length
     self.__width = width
     self.__area = length * width
     self.__tf = TerrainFactory()
     self.map = []
     self.ds_nodes = []
     self.__up_loc = 0
     self.center_pt = (int(self.__length/2),int(self.__width/2))
     self.__gen_initial_map(initial_open)
Ejemplo n.º 5
0
 def __init__(self, length, width):
     self.length = length
     self.width = width
     if self.width % 2 == 0: self.width -= 1
     if self.length % 2 == 0: self.length -= 1
     self.map = []
     self.__tf = TerrainFactory()
     self.__ds_nodes = []
     self.__wall = self.__tf.get_terrain_tile(CYBERSPACE_WALL)
     self.__floor = self.__tf.get_terrain_tile(CYBERSPACE_FLOOR)
     
     self.__gen_initial_map()
Ejemplo n.º 6
0
 def __init__(self, length, width, top, bottom):
     self.__length = length
     self.__width = width
     self.__max_depth = 3
     self._map = []
     self.__tf = TerrainFactory()
     self.__top = top
     self.__bottom = bottom
     self.rooms = {}
     
     # handy place-holders
     self.__wall = self.__tf.get_terrain_tile(WALL)
     self.__floor = self.__tf.get_terrain_tile(FLOOR)
     self.__ocean = self.__tf.get_terrain_tile(OCEAN)
     
     # start the map off as all walls
     for r in range(self.__length):
         self._map.append([self.__ocean] * self.__width)
     
     self.upStairs = ''
     self.downStairs = ''
Ejemplo n.º 7
0
class CA_CaveFactory:
    def __init__(self,length,width,initial_open=0.40):
        self.__length = length
        self.__width = width
        self.__area = length * width
        self.__tf = TerrainFactory()
        self.map = []
        self.ds_nodes = []
        self.__up_loc = 0
        self.center_pt = (int(self.__length/2),int(self.__width/2))
        self.__gen_initial_map(initial_open)

    def set_cell(self,r, c, sqr):
        self.map[r][c] = sqr

    # 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] = self.__tf.get_terrain_tile(PERM_WALL)
            self.map[j][self.__width-1] = self.__tf.get_terrain_tile(PERM_WALL)

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

    def __gen_initial_map(self,initial_open):
        for r in range(0,self.__length):
            row = []
            ds_row = []
            for c in range(0,self.__width):
                ds_row.append(DSNode((r,c)))
                row.append(self.__tf.get_terrain_tile(WALL))
            self.ds_nodes.append(ds_row)
            self.map.append(row)

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

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

            if self.map[rand_r][rand_c].get_type() == WALL:
                self.set_cell(rand_r,rand_c,self.__tf.get_terrain_tile(FLOOR))
                open_count -= 1

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

        for r in range(0,self.__length):
            for c in range(0,self.__width):
                ch = self.map[r][c].get_ch()
                if ch == ' ':
                    ch = '#'

                print ch,
            print

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

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

        return count

    def up_stairs_loc(self):
        return self.__up_loc

    def gen_map(self,set_stairs=[]):
        for r in range(1,self.__length-1):
            for c in range(1,self.__width-1):
                self.__update_cell(r,c)

        self.__join_rooms()
        self.add_stairs(set_stairs)
        self.lvl_width = self.__width
        self.lvl_length = self.__length

        return self.map

    def __update_cell(self,r,c):
        wall_count = self.__adj_wall_count(r,c)

        if self.map[r][c].get_type() == FLOOR:
            if wall_count > 5:
                self.set_cell(r,c,self.__tf.get_terrain_tile(WALL))
        elif wall_count < 4:
            self.set_cell(r,c,self.__tf.get_terrain_tile(FLOOR))

    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):
                self.__union_adj_sqr(r,c)

        _nodes = []
        for _row in self.ds_nodes:
            for _node in _row:
                _n = _node.value
                if self.map[_n[0]][_n[1]].get_type() == FLOOR:
                    _nodes.append(_node)
            
        all_caves = split_sets(_nodes)
        
        for cave in all_caves.keys():
            self.join_points(all_caves[cave][0].value)
            
    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
            
            union(self.ds_nodes[next_pt[0]][next_pt[1]], self.ds_nodes[pt1[0]][pt1[1]])
            self.set_cell(next_pt[0],next_pt[1],self.__tf.get_terrain_tile(FLOOR))

            pt1 = next_pt

    def stop_drawing(self,pt,npt,cpt):
        parent_pt = find(self.ds_nodes[pt[0]][pt[1]])
        parent_npt = find(self.ds_nodes[npt[0]][npt[1]])
        parent_cpt = find(self.ds_nodes[cpt[0]][cpt[1]])
        
        if parent_npt == parent_cpt:
            return True
            
        if parent_pt != parent_npt and self.map[npt[0]][npt[1]].get_type() == FLOOR:
            return True
        else:
            return False

    def in_bounds(self,pt):
        if pt[0] in (0,self.__length-1) or pt[1] in (0,self.__width-1):
            return 0
        else:
            return 1

    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 add_stairs(self, set_stairs):
        while 1:
            dr = randrange(1,self.__length-1)
            dc = randrange(1,self.__width-1)
            ur = randrange(0,self.__length)
            uc = randrange(0,self.__width)
        
            if (dr,dc) != (ur,uc) and self.map[dr][dc].get_type() == FLOOR and self.map[ur][uc].get_type() == FLOOR:
                break

        if len(set_stairs) == 0:
            _up = True
            _down = True
        else:
            _up = set_stairs[0]
            _down = set_stairs[1]
        
        if _up: 
            self.__up_loc = (ur,uc)
            self.upStairs = (ur,uc)
            self.set_cell(ur,uc,self.__tf.get_terrain_tile(UP_STAIRS))
        if _down:
            self.__down_loc = (dr,dc)
            self.downStairs = (dr,dc)
            self.set_cell(dr,dc,self.__tf.get_terrain_tile(DOWN_STAIRS))
         
    def __union_adj_sqr(self,sr,sc):
        if self.map[sr][sc].get_type() != FLOOR:
            return
        
        loc = (sr,sc)

        for r in (-1,0,1):
            for c in (-1,0,1):
                if self.map[sr+r][sc+c].get_type() == FLOOR \
                        and self.ds_nodes[sr][sc].parent != self.ds_nodes[sr+r][sc+c].parent:
                    union(self.ds_nodes[sr][sc], self.ds_nodes[sr+r][sc+c])
Ejemplo n.º 8
0
class NewComplexFactory:
    def __init__(self, length, width, top, bottom):
        self.__length = length
        self.__width = width
        self.__max_depth = 3
        self._map = []
        self.__tf = TerrainFactory()
        self.__top = top
        self.__bottom = bottom
        self.rooms = {}
        
        # handy place-holders
        self.__wall = self.__tf.get_terrain_tile(WALL)
        self.__floor = self.__tf.get_terrain_tile(FLOOR)
        self.__ocean = self.__tf.get_terrain_tile(OCEAN)
        
        # start the map off as all walls
        for r in range(self.__length):
            self._map.append([self.__ocean] * self.__width)
        
        self.upStairs = ''
        self.downStairs = ''
                
    def __set_staircase(self,stairs):
        while 1:
            r = randrange(0,self.__length)
            c = randrange(0,self.__width)

            if self._map[r][c].get_type() == FLOOR:
                self._map[r][c] = stairs
                break

        return (r,c)

    def __set_stairs(self):
        if not self.__top:
            self.upStairs = self.__set_staircase(self.__tf.get_terrain_tile(UP_STAIRS))
        if not self.__bottom:
            self.downStairs = self.__set_staircase(self.__tf.get_terrain_tile(DOWN_STAIRS))
            
    def __carve_rooms(self, rooms, depth):
        depth += 1
        if depth > self.__max_depth: return
        
        for _room in rooms:
            _rooms = []
            if _room == None: continue
            if _room.quadrant == 'sw':
                _rooms.append(self._make_se_room(_room.sw))
                _rooms.append(self._make_nw_room(_room.sw)) 
            if _room.quadrant == 'nw': 
                _rooms.append(self._make_ne_room(_room.nw))
                _rooms.append(self._make_sw_room(_room.nw))
            if _room.quadrant == 'ne':
                _rooms.append(self._make_se_room(_room.ne))
                _rooms.append(self._make_nw_room(_room.ne))
            if _room.quadrant == 'se':
                _rooms.append(self._make_sw_room(_room.se))
                _rooms.append(self._make_ne_room(_room.se))
            _rooms = [_room for _room in _rooms if _room != None]
            if len(_rooms) > 0:
                self.__carve_rooms(_rooms,depth)

    def __fill_in_floors(self, nw, se):
        for _row in range(nw[0]+1,se[0]):
            for _col in range(nw[1]+1,se[1]):
                self._map[_row][_col] = self.__floor
            
    def _make_sw_room(self, sqr):
        _ne = sqr
        _width = randrange(3,10)
        _length = randrange(3,10)

        if sqr[0] + _length >= self.__length:
            _down = self.__length -1
        else:
            _down = sqr[0] + _length

        if sqr[1] - _width <= 0:
            _left = 1
        else:
            _left = sqr[1] - _width

        if _down > self.__length - 3 or _left < 3:
            return
            
        # draw right wall
        for _row in range(sqr[0],_down):
            self._map[_row][sqr[1]] = self.__wall
        _se = (_row+1,sqr[1])
        sqr = (_row+1,sqr[1])
        
        # draw bottom wall
        for _col in range(sqr[1],_left,-1):
            self._map[sqr[0]][_col] = self.__wall
        _sw = (sqr[0],_col-1)
        sqr = (sqr[0],_col-1)

        # draw left wall
        for _row in range(sqr[0],_ne[0],-1):
            self._map[_row][sqr[1]] = self.__wall
        _nw = (_row-1,sqr[1])
        sqr = (_row-1,sqr[1])
    
        # draw top wall
        for _col in range(sqr[1],_ne[1]):
            self._map[sqr[0]][_col] = self.__wall

        self.__fill_in_floors(_nw, _se)
        return Room('sw', _ne, _se, _nw, _sw)
    
    def _make_nw_room(self, sqr):
        _se = sqr
        _width = randrange(3,10)
        _length = randrange(3,10)
    
        if sqr[0] - _length <= 0:
            _up = 1
        else:
            _up = sqr[0] - _length

        if sqr[1] - _width <= 0:
            _left = 1
        else:
            _left = sqr[1] - _width

        if _left < 3 or _up < 3:
            return
            
        # draw bottom wall
        for _col in range(sqr[1],_left,-1):
            self._map[sqr[0]][_col] = self.__wall
        _sw = (sqr[0],_col-1)
        sqr = (sqr[0],_col-1)

        # draw left wall
        for _row in range(sqr[0],_up-1,-1):
            self._map[_row][sqr[1]] = self.__wall
        _nw = (_row-1,sqr[1])
        sqr = (_row-1,sqr[1])

        # draw top wall
        for _col in range(sqr[1],_se[1]):
            self._map[sqr[0]][_col] = self.__wall
        _ne = (sqr[0],_col+1)
        sqr = (sqr[0],_col+1)

        # draw right wall
        for _row in range(_ne[0],_se[0]):
            self._map[_row][sqr[1]] = self.__wall

        self.__fill_in_floors(_nw, _se)
        return Room('nw', _ne, _se, _nw, _sw)
        
    def _make_ne_room(self, sqr):
        _sw = sqr
        _width = randrange(3,10)
        _length = randrange(3,10)
        
        if sqr[0] - _length <= 0:
            _up = 1
        else:
            _up = sqr[0] - _length

        if sqr[1] + _width >= self.__width:
            _right = self.__width - 1
        else:
            _right = sqr[1] + _width
            
        if _up < 2 or _right > self.__width - 2:
            return 
        
        # draw bottom wall
        for _col in range(sqr[1],_right):
            self._map[sqr[0]][_col] = self.__wall
        _se = (sqr[0],_col+1)
        sqr = (sqr[0],_col+1)

        # draw right wall
        for _row in range(_se[0],_up-1,-1):
            self._map[_row][sqr[1]] = self.__wall
        _ne = (_row-1,sqr[1])
        sqr = (_row-1,sqr[1])
    
        # draw top wall
        for _col in range(sqr[1],_sw[1],-1):
            self._map[sqr[0]][_col] = self.__wall
        _nw = (sqr[0],_col-1)
        sqr = (sqr[0],_col-1)

        # draw left wall
        for _row in range(sqr[0],_sw[0]):
            self._map[_row][sqr[1]] = self.__wall

        self.__fill_in_floors(_nw, _se)
        return Room('ne', _ne, _se, _nw, _sw)
    
    def _make_se_room(self, sqr):
        _nw = sqr
        _width = randrange(3,10)
        _length = randrange(3,10)
        
        if sqr[0] + _length >= self.__length:
            _down = self.__length - 1
        else:
            _down = sqr[0] + _length

        if sqr[1] + _width >= self.__width:
            _right = self.__width - 1
        else:
            _right = sqr[1] + _width
        
        if _down > self.__length -3 or _right > self.__width - 3:
            return 
            
        # draw top wall
        for _col in range(sqr[1],_right):
            self._map[sqr[0]][_col] = self.__wall
        _ne = (sqr[0],_col+1)
        sqr = (sqr[0],_col+1)

        # draw right wall
        for _row in range(sqr[0],_down):
            self._map[_row][sqr[1]] = self.__wall
        _se = (_row+1,sqr[1])
        sqr = (_row+1,sqr[1])

        # draw bottom wall
        for _col in range(sqr[1],_nw[1],-1):
            self._map[sqr[0]][_col] = self.__wall
        _sw = (sqr[0],_col-1)
        sqr = (sqr[0],_col-1)

        # draw left wall
        for _row in range(sqr[0], _nw[0],-1):
            self._map[_row][sqr[1]] = self.__wall

        self.__fill_in_floors(_nw, _se)
        return Room('se', _ne, _se, _nw, _sw)
    
    def __in_bounds(self, r, c):
        if r < 2 or r >= self.__length-1:
            return False
        if c < 2 or c >= self.__width-1:
            return False

        return True
    
    def __mark_adjacent(self, _sqr, _sqrs):
        _value = _sqr.value
        _m_row = _value[0]
        _m_col = _value[1]
        
        for r in (-1, 0, 1):
            for c in (-1, 0, 1):
                if self._map[_m_row+r][_m_col+c].get_type() == FLOOR:
                    union(_sqr, _sqrs[_m_row+r][_m_col+c])
    
    def __pick_dir(self, _start):
        _row = _start[0]
        _col = _start[1]
        _roll = randrange(0,5)
    
        if _roll < 3:
            if _row < 25 and _col < 35:
                    return choice([(1,0),(0,1),])
            if _row < 25 and _col > 35:
                return choice([(1,0),(0,-1)])
            if _row > 25 and _col > 35:
                return choice([(-1,0),(0,-1)])
            if _row > 25 and _col < 35:
                return choice([(-1,0),(0,1)])
    
        return choice([(1,0),(0,1),(-1,0),(0,-1)])
    
    def __look_ahead(self, _sqrs, _start, _dir, r, c):
        if self._map[r][c].get_type() == FLOOR:
            return True
    
        _next_r = r+_dir[0]
        _next_c = c+_dir[1]
        if not self.__in_bounds(_next_r, _next_c):
            return False
        
        if _next_r >= len(_sqrs) or _next_c >= len(_sqrs[0]):
            return False

        if find(_start) == find(_sqrs[_next_r][_next_c]):
            return True
        
        return False
    
    # Room generator sometimes carves out things like:
    #
    #   ##########
    #   #   ##   #
    #   #   ##   #
    #   ##########
    #
    # So we can join with a simple door, so instead
    # we'll make a small hallway.
    def __check_for_short_hallway(self, r, c, _dir, _sqrs, start):
        _second_r = r + _dir[0]
        _second_c = c + _dir[1]
        _third_r = _second_r + _dir[0]
        _third_c = _second_c + _dir[1]

        if not self.__in_bounds(_second_r, _second_c) or not self.__in_bounds(_third_r, _third_c):
            return False
        if not self._map[_second_r][_second_c].get_type() == WALL:
            return False
        if not self._map[_third_r][_third_c].get_type() == FLOOR:
            return False
        if find(start) == find(_sqrs[_third_r][_third_c]):
            return False
    
        self._map[r][c] = self.__floor
        union(start, _sqrs[r][c])
        self._map[_second_r][_second_c] = self.__floor
        union(start, _sqrs[_second_r][_second_c])
        union(start, _sqrs[_third_r][_third_c])
    
        return True

    def __vet_door(self, r, c, _dir, _sqrs, start):
        _next_r = r + _dir[0]
        _next_c = c + _dir[1]

        if not self.__in_bounds(_next_r, _next_c):
            return False
        if self._map[_next_r][_next_c].get_type() != FLOOR:
            return False
        if find(start) == find(_sqrs[_next_r][_next_c]):
            return False

        return True
    
    def __merge_rooms(self, _sqrs, _floors):
        _rooms = split_sets(_floors)
        while len(_rooms.keys()) > 1:
            _start = self.__pick_room(_rooms)
            _dir = self.__pick_dir(_start.value)
            r = _start.value[0]+_dir[0]
            c = _start.value[1]+_dir[1]
            
            _reject = False
            while self.__look_ahead(_sqrs, _start, _dir, r, c):
                r += _dir[0]
                c += _dir[1]
                
                if not self.__in_bounds(r,c):
                    _reject = True
                    break
            if _reject: continue
            
            if not self.__check_for_short_hallway(r, c, _dir, _sqrs, _start):
                if self.__vet_door(r, c, _dir, _sqrs, _start):
                    union(_start, _sqrs[r][c])
                    union(_start, _sqrs[r+_dir[0]][c+_dir[1]])
                    if randrange(4) < 3:
                        self._map[r][c] = self.__tf.get_terrain_tile(DOOR)
                    else:
                        self._map[r][c] = self.__floor
            _rooms = split_sets(_floors)
    
    # Pick the smallest room first, which should make us more likely to
    # find a good door when there is one small room left and everything 
    # else has been merged.
    def __pick_room(self, _rooms):
        _size = 1000
    
        for _r in _rooms.keys():
            if len(_rooms[_r]) < _size:
                _room = _r
                _size = len(_rooms[_r])

        return choice(_rooms[_room])
    
    # I'm only going to bother with rooms bigger than six squares
    def __record_rooms(self, floor_sets):
        _count = 0
        for _key in floor_sets:
            if len(floor_sets[_key]) > 6:
                for _floor in floor_sets[_key]:
                    self.rooms.setdefault(_count,[])
                    self.rooms[_count].append((_floor.value[0], _floor.value[1]))
                _count += 1
                
    def __discover_rooms(self):
        _sqrs = []
        for r in range(1, len(self._map) - 1):
            _row = []
            for c in range(1, len(self._map[0]) - 1):
                _row.append(DSNode((r,c, self._map[r][c])))
            _sqrs.append(_row)
            
        _floors = []
        for _row in _sqrs:
            for _item in _row:
                if _item.value[2].get_type() == FLOOR:
                    _floors.append(_item)
                    self.__mark_adjacent(_item, _sqrs)
        
        self.__record_rooms(split_sets(_floors))

        self.__merge_rooms(_sqrs, _floors)
    
    def remove_up_stairs_from_rooms(self):
        if self.upStairs != '':
            for _room in self.rooms.keys():
                if self.upStairs in self.rooms[_room]:
                    del self.rooms[_room]

    def gen_map(self):
        _initial = (self.__length/2,self.__width/2)

        _rooms = []
        _rooms.append(self._make_sw_room(_initial))
        _rooms.append(self._make_nw_room(_initial))
        _rooms.append(self._make_ne_room(_initial))
        _rooms.append(self._make_se_room(_initial))
        
        self.__carve_rooms(_rooms, 0)
        self.__discover_rooms()
        self.__set_stairs()
        
        return self._map
        
    def print_grid(self):
        for _row in self._map:
            _line = ''
            for _item in _row:
                _ch = _item.get_ch()
                if _ch == ' ':
                    ch = '#'
                            
                _line += _ch
            print _line
Ejemplo n.º 9
0
 def __add_exit_nodes(self):
     _tf = TerrainFactory()
     
     for j in range(3):
         self.place_sqr(_tf.get_terrain_tile(EXIT_NODE), CYBERSPACE_FLOOR)
Ejemplo n.º 10
0
class ProvingGroundsLevel(GameLevel):
    def __init__(self, dm, level_num, length, width):
        GameLevel.__init__(self, dm, level_num, length, width, 'proving grounds')
        
    def generate_level(self):
        self.map = []
        self.generate_map()
        
        for j in range(randrange(5, 16)):
            self.add_monster()
            
    def generate_map(self):
        self.tf = TerrainFactory()
        
        _map = []
        
        # initialize map
        _ca = CA_CaveFactory(self.lvl_length, self.lvl_width - 10, 0.45)
        _cave = _ca.gen_map([False,False])
        
        for _row in _cave:
            _line = [self.tf.get_terrain_tile(PERM_WALL)]
            _line += [self.tf.get_terrain_tile(PERM_WALL) for j in range(4)]
            _line += _row
            _line += [self.tf.get_terrain_tile(PERM_WALL) for j in range(4)]
            _line.append(self.tf.get_terrain_tile(PERM_WALL))
            _map.append(_line)
        
        self.map = _map
        
        # clear out middle section of map
        for _row in range(8, self.lvl_length - 9):
            for _col in range(7, self.lvl_width - 10):
                self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
                
        # Now draw the tunnel entrance tunnel
        self.draw_entrance_tunnel()
        if self.level_num == 13:
            self.draw_exit_tunnel()
        self.add_buildings()
        self.add_toxic_pools()
        
    def draw_entrance_tunnel(self):
        _row = randrange(5, self.lvl_length-5)
        _col = 3
        self.map[_row][1] = SpecialFloor('up')
        self.map[_row][2] = self.tf.get_terrain_tile(FLOOR)
        self.player_start_loc = (_row, 2)
        
        while self.map[_row][_col].get_type() != FLOOR:
            self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
            if randrange(4) == 0 and _row < self.lvl_width - 5:
                _row += 1
                self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
            _col += 1
            
    def draw_exit_tunnel(self):
        _row = randrange(5, self.lvl_length-5)
        _col = self.lvl_width - 2
        self.map[_row][_col] = SpecialFloor('down')
        _col -= 1
        
        while self.map[_row][_col].get_type() != FLOOR:
            self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
            if randrange(4) == 0 and _row < self.lvl_width - 5:
                _row += 1
                self.map[_row][_col] = self.tf.get_terrain_tile(FLOOR)
            _col -= 1
    
    def add_pool(self, pool_type):
        # get starting point
        while True:
            _row = randrange(2, self.lvl_length - 2)
            _col = randrange(2, self.lvl_width - 2)
            if self.map[_row][_col].get_type() == FLOOR:
                break
                
        self.map[_row][_col] = self.tf.get_terrain_tile(pool_type)
        for _dr in (-1, 0, 1):
            for _dc in (-1, 0, 1):
                if self.map[_row + _dr][_col + _dc].get_type() == FLOOR and randrange(5) == 0:
                    self.map[_row + _dr][_col + _dc] = self.tf.get_terrain_tile(pool_type)
                     
    def add_toxic_pools(self):
        for j in range(randrange(1,4)):
            self.add_pool(TOXIC_WASTE)
        for j in range(randrange(1,4)):
            self.add_pool(ACID_POOL)

    def get_rectangular_building(self):
        _sqrs = []
        _start_r = randrange(5, self.lvl_length - 10)
        _start_c = randrange(15, self.lvl_width - 15)
        _length = randrange(4, 8)
        _width = randrange(4, 8)
        
        for c in range(_width):
            _sqrs.append([_start_r, _start_c + c, self.tf.get_terrain_tile(WALL)])
        for r in range(1, _length):
            _sqrs.append([_start_r+r, _start_c, self.tf.get_terrain_tile(WALL)])
            _sqrs.append([_start_r+r, _start_c + _width - 1, self.tf.get_terrain_tile(WALL)])
            for c in range(1, _width - 1):
                _sqrs.append([_start_r+r, _start_c + c, self.tf.get_terrain_tile(FLOOR)])
        for c in range(_width):
            _sqrs.append([_start_r + _length, _start_c + c, self.tf.get_terrain_tile(WALL)])
            
        # place door
        _walls = [_sqr for _sqr in _sqrs if _sqr[2].get_type() == WALL]
        while len(_walls) > 0:
            _w = choice(_walls)
            _walls.remove(_w)
            
            if _w[0] == _start_r:
                if _w[1] == _start_c or _w[1] == _start_c + _width - 1:
                    continue
                if self.map[_w[0]-1][_w[1]].get_type() not in (WALL, PERM_WALL, DOOR):
                    _w[2] = self.tf.get_terrain_tile(DOOR)
                    break
            if _w[0] == _start_r + _length:
                if _w[1] == _start_c or _w[1] == _start_c + _width - 1:
                    continue
                if self.map[_w[0]+1][_w[1]].get_type() not in (WALL, PERM_WALL, DOOR):
                    _w[2] = self.tf.get_terrain_tile(DOOR)
                    break
            if _w[1] == _start_c:
                if _w[0] == _start_r or _w[0] == _start_r + _length:
                    continue
                if self.map[_w[0]][_w[1]-1].get_type() not in (WALL, PERM_WALL, DOOR):
                    _w[2] = self.tf.get_terrain_tile(DOOR)
                    break
            if _w[1] == _start_c + _width - 1:
                if _w[0] == _start_r or _w[0] == _start_r + _length:
                    continue
                if self.map[_w[0]][_w[1]+1].get_type() not in (WALL, PERM_WALL, DOOR):
                    _w[2] = self.tf.get_terrain_tile(DOOR)
                    break
       
        return _sqrs

    # Not time efficient, but developer brain efficient...
    def will_overlap(self, buildings, new_building):
        _new_sqrs = set([(_p[0],_p[1]) for _p in new_building])
        for _b in buildings:
            _sqrs = set([(_p[0],_p[1]) for _p in _b])
            if len(_new_sqrs.intersection(_sqrs)):
                return True
            
        return False
                
    def make_ambush_building(self, building):
        _top_wall = self.lvl_length
        _bottom_wall = 0
        _left_wall = self.lvl_width
        _right_wall = 0
        
        for _sqr in building:
            if _sqr[0] < _top_wall:
                _top_wall = _sqr[0]
            if _sqr[0] > _bottom_wall:
                _bottom_wall = _sqr[0]
            if _sqr[1] < _left_wall:
                _left_wall = _sqr[1]
            if _sqr[1] > _right_wall:
                _right_wall = _sqr[1]
            if _sqr[2].get_type() == DOOR:
                _door = (_sqr[0], _sqr[1])
            
        _gt = MonsterFactory.get_monster_by_name(self.dm, "gun turret", 0, 0)
        # We want to make the gun turret either straight across from the 
        # door or at right angles.
        if _door[0] == _top_wall:
            self.add_monster_to_dungeon(_gt, _bottom_wall - 1, _door[1])
        elif _door[0] == _bottom_wall:
            self.add_monster_to_dungeon(_gt, _top_wall + 1, _door[1])
        elif _door[1] == _left_wall:
            self.add_monster_to_dungeon(_gt, _door[0], _right_wall - 1)
        elif _door[1] == _right_wall:
            self.add_monster_to_dungeon(_gt, _door[0], _left_wall + 1)
    
    def make_barracks(self, building):
        for j in range(randrange(2,4)):
            _cy = MonsterFactory.get_monster_by_name(self.dm, "cyborg soldier", 0, 0)
            place_monster(building, self, _cy)
        
        _if = ItemFactory()
        _box = Items.Box('footlocker')
        for j in range(randrange(3)):
            _roll = randrange(6)
            if _roll == 0:
                _box.add_item(_if.get_stack('shotgun shell', 6, True))
            elif _roll == 1:
                _box.add_item(_if.get_stack('grenade', 4, True))
            elif _roll == 2:
                _box.add_item(_if.get_stack('stimpak', 3, True))
            elif _roll == 3:
                _box.add_item(_if.get_stack('machine gun clip', 3, True))
            elif _roll == 4:
                _box.add_item(_if.get_stack('9mm clip', 3, True))
            else:
                _box.add_item(_if.get_stack('medkit', 3, True))
        place_item(building, self, _box)
    
    def make_repair_shop(self, building):
        _doc = MonsterFactory.get_monster_by_name(self.dm, "repair bot", 0, 0)
        place_monster(building, self, _doc)
        
        for j in range(randrange(2)):
            _ed = MonsterFactory.get_monster_by_name(self.dm, "ed-209", 0, 0)
            place_monster(building, self, _ed)
        for j in range(randrange(1,4)):
            _sb = MonsterFactory.get_monster_by_name(self.dm, "security bot", 0, 0)
            place_monster(building, self, _sb)
        
        _if = ItemFactory()
        for j in range(randrange(1,4)):
            _roll = randrange(10)
            if _roll < 7:
                _item = _if.get_stack('battery', 3, True)
            elif _roll < 9:
                _item = _if.gen_item('targeting wizard')
            else:
                _item = _if.gen_item('icannon')
            place_item(building, self, _item)
            
    def populate_building(self, building):
        _roll = randrange(5)
        if _roll < 2:
            self.make_repair_shop(building)
        elif _roll < 4:
            self.make_barracks(building)
        else:
            self.make_ambush_building(building)

    def add_buildings(self):
        _buildings = []

        for j in range(randrange(3,7)):
            _building = self.get_rectangular_building()
            if not self.will_overlap(_buildings, _building):
                _buildings.append(_building)

        for _b in _buildings:
            for _s in _b:
                self.map[_s[0]][_s[1]] = _s[2]
            self.populate_building(_b)
            
    def __get_monster(self):
        _rnd =  randrange(0, 16)
        if _rnd in range(0, 2):
            _name = 'reanimated unionized maintenance worker'
        elif _rnd in range(2, 4):
            _name = 'wolvog'
        elif _rnd in range(4, 6):
            _name = 'security bot'
        elif _rnd in range(5, 6):
            _name = 'mq1 predator'        
        elif _rnd in range(6,7):
            _name = 'ninja'
        elif _rnd in range(7,9):
            _name = 'beastman'
        elif _rnd in range(9, 12):
            _name = 'cyborg soldier'
        elif _rnd in range(12, 14):
            _name = 'cyborg sergeant'
        else:
            _name = 'ed-209'
            
        return MonsterFactory.get_monster_by_name(self.dm, _name, 0, 0)
            
    def add_monster(self):
        _monster = self.__get_monster()
        GameLevel.add_monster(self, _monster)
Ejemplo n.º 11
0
class Maze(object):
    def __init__(self, length, width):
        self.length = length
        self.width = width
        if self.width % 2 == 0: self.width -= 1
        if self.length % 2 == 0: self.length -= 1
        self.map = []
        self.__tf = TerrainFactory()
        self.__ds_nodes = []
        self.__wall = self.__tf.get_terrain_tile(CYBERSPACE_WALL)
        self.__floor = self.__tf.get_terrain_tile(CYBERSPACE_FLOOR)
        
        self.__gen_initial_map()
        
    def __gen_initial_map(self):
        for r in range(self.length):
            if r % 2 == 0:
                self.map.append([self.__wall] * self.width)
            else:
                _row = []
                _ds_row = []
                for c in range(self.width):
                    if c % 2 == 0:
                        _row.append(self.__wall)
                    else:
                        _row.append(self.__floor)
                        _ds_row.append(DSNode((r,c)))
                self.__ds_nodes.append(_ds_row)
                self.map.append(_row)
    
    def in_bounds(self, row, col):
        return row >= 0 and row < self.length and col >= 0 and col < self.width
        
    def __get_candidate(self, node):
        _candidates = []
        _nr = node.value[0]
        _nc = node.value[1]
        
        if self.in_bounds(_nr - 2, _nc) and self.map[_nr-1][_nc].get_type() == CYBERSPACE_WALL:
            _c_node = self.__ds_nodes[_nr/2-1][_nc/2]
            if find(_c_node) != find(node):
                _candidates.append((_c_node, _nr-1, _nc))
        if self.in_bounds(_nr + 2, _nc) and self.map[_nr+1][_nc].get_type() == CYBERSPACE_WALL:
            _c_node = self.__ds_nodes[_nr/2+1][_nc/2]
            if find(_c_node) != find(node):
                _candidates.append((_c_node, _nr+1, _nc))
        if self.in_bounds(_nr, _nc - 2) and self.map[_nr][_nc-1].get_type() == CYBERSPACE_WALL:
            _c_node = self.__ds_nodes[_nr/2][_nc/2-1]
            if find(_c_node) != find(node):
                _candidates.append((_c_node, _nr, _nc-1))
        if self.in_bounds(_nr, _nc + 2) and self.map[_nr][_nc+1].get_type() == CYBERSPACE_WALL:
            _c_node = self.__ds_nodes[_nr/2][_nc/2+1]
            if find(_c_node) != find(node):
                _candidates.append((_c_node, _nr, _nc+1))
        
        if len(_candidates) > 0:
            return choice(_candidates)
        else:
            return None 
        
    def gen_map(self):
        for _row in self.__ds_nodes:
            for _node in _row:
                _merge = self.__get_candidate(_node)
                if _merge != None:
                    union(_node, _merge[0])
                    self.map[_merge[1]][_merge[2]] = self.__floor
        return self.map
Ejemplo n.º 12
0
    def __generate_map(self):
        _map = []
        
        _if = ItemFactory()
        _tf = TerrainFactory()
        
        # make all border squares walls
        # This could be moved to a superclass
        row = []
        for j in range(0, self.lvl_width):
            row.append(_tf.get_terrain_tile(PERM_WALL))
        _map.append(row)

        for r in range(1, self.lvl_length-1):
            row = []
            row.append(_tf.get_terrain_tile(PERM_WALL))

            for c in range(1, self.lvl_width-1):
                rnd = random()
                
                if rnd < 0.50:
                    row.append(_tf.get_terrain_tile(ROAD))
                elif rnd < 0.90:
                    row.append(_tf.get_terrain_tile(GRASS))
                else:
                    row.append(_tf.get_terrain_tile(TREE))
            row.append(_tf.get_terrain_tile(PERM_WALL))
            _map.append(row)
        row = []
        for j in range(0, self.lvl_width):
            row.append(_tf.get_terrain_tile(PERM_WALL))
        _map.append(row)
        
        # generate the tower section
        _tower = TowerFactory(length = 20, width = 30, top = True, bottom = False)
        _tower.gen_map()
        self.upStairs = None
        self.downStairs = _tower.downStairs
        
        for r in range(0, 20):
            for c in range(0, 30):
                _row = 10 + r
                _col = self.lvl_width- 31 + c
                _map[_row][_col] = _tower.get_cell(r,c)
                if _map[_row][_col].get_type() == DOOR and random() > 0.6:
                    _map[_row][_col].broken = True
                    _map[_row][_col].open()
                
        # beat up the tower a bit
        for x in range(randrange(100, 200)):
            r = 10 + randrange(0,20)
            c = self.lvl_width - 31 + randrange(0, 30)
            if _map[r][c].get_type() != DOWN_STAIRS:
                if random() < 0.75:
                    _map[r][c] = _tf.get_terrain_tile(ROAD)
                else:
                    _map[r][c] = _tf.get_terrain_tile(GRASS)

        # Add double door main entrance
        for r in range(15,25):
            if _map[r][self.lvl_width-30].get_type() == FLOOR and _map[r+1][self.lvl_width-30].get_type() == FLOOR:
                break
        _map[r][self.lvl_width-31] = _tf.get_terrain_tile(DOOR)
        _map[r+1][self.lvl_width-31] = _tf.get_terrain_tile(DOOR)

        for c in range(0, 30):
            _map[29][self.lvl_width-31+c] = _tf.get_terrain_tile(WALL)

        _box = Items.Box()
        _box_placed = False
        while not _box_placed:
            _col = randrange(self.lvl_width-30, self.lvl_width)
            _row = randrange(self.lvl_length-20, self.lvl_length)
            if _map[_row][_col].get_type() not in (DOOR, WALL, PERM_WALL, DOWN_STAIRS):
                self.add_item_to_sqr(_row, _col, _box)
                _box_placed = True

        for x in range(randrange(7)):
            _box.add_item(_if.gen_item('ritalin', 1))
        for x in range(randrange(19)):
            _box.add_item(_if.gen_item('shotgun shell', 1))
        for x in range(randrange(4)):
            _box.add_item(_if.gen_item('flare', 1))
        if randrange(4) > 2:
            _box.add_item(_if.gen_item('medkit', 1))
            
        return _map