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)
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)
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 __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 __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 __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 = ''
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])
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
def __add_exit_nodes(self): _tf = TerrainFactory() for j in range(3): self.place_sqr(_tf.get_terrain_tile(EXIT_NODE), CYBERSPACE_FLOOR)
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)
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
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