1 """ Procedural map generation for levels """
6 i = random.randint(0,100)
10 def __init__(self, region):
13 self.regions = [region]
14 self.max_connections = 1
20 Check if the room is linked to another room
21 :return: Whether the room has any links or not
23 return len(self.passages) + len(self.tunnels) > 0
25 def add_passage(self, room_region, new_region):
26 """ Add a passage link between rooms
27 :param room_region: coordinate of region from which we are linking
28 :param new_region: coordinate of region to which we are linking
33 def add_region(self, region):
35 Add a new region into an existing room
36 :param region: region coordinates to be added to room
39 self.regions.append(region)
41 def connect_rooms(self, other_rooms):
42 """ Find the nearest rooms to this room
43 :param other_rooms: list of Rooms objects that we are searching
50 for local_region in self.regions:
51 for room in other_rooms:
54 for new_region in room.regions:
56 math.sqrt((local_region[0] - new_region[0]) ** 2 +
57 (local_region[1] - new_region[1]) ** 2))
58 other_tile.append(new_region)
59 this_tile.append(local_region)
60 target_rooms.append(room)
62 sorted_indices = [i[0] for i in sorted(enumerate(distance),
64 for index in sorted_indices:
65 if len(self.passages) + len(self.tunnels) >= self.max_connections:
67 if not target_rooms[index].is_linked():
68 self.link_passage(this_tile[index], other_tile[index])
69 target_rooms[index].link_passage(
70 other_tile[index], this_tile[index])
72 def link_passage(self, local_tile, foriegn_tile):
73 """ Link a passage between two rooms
74 :param local_tile: tile in this room to which we wish to link
75 :param foriegn_tile: tile in another room to which we wish to link
78 self.passages.append([local_tile, foriegn_tile])
90 dist_from_other_rooms = 0
95 def __init__(self, width, height, no_rooms, min_room_size, max_room_size,
96 dist_from_edge, dist_from_other_rooms, region_size):
97 """ Initialize the level parameters
101 self.no_rooms = no_rooms
102 self.min_room_size = min_room_size
103 self.max_room_size = max_room_size
104 self.dist_from_edge = dist_from_edge
105 self.dist_from_other_rooms = dist_from_other_rooms
106 self.region_size = region_size
109 """ Generate a random level map
111 self.generate_rooms()
112 regions_selected = random.sample(range(self.regions),
113 min(self.regions, self.no_rooms))
114 row = ['#' for x in range(self.width * self.region_size)]
115 self.map = [row[:] for x in range(self.height * self.region_size)]
116 print('Regions: %s' % str(regions_selected))
117 for region in regions_selected:
118 self.rooms[region].connect_rooms(
119 [self.rooms[i] for i in regions_selected])
120 self.generate_tiles(region)
122 def generate_rooms(self):
123 """ Generate a random level region map
125 row = [0 for x in range(self.width)]
126 self.region_map = [row[:] for x in range(self.height)]
127 for h in range(self.height):
128 for w in range(self.width):
129 random_number = random.randint(0, 2)
130 increment_region = False
132 self.region_map[h][w] = self.regions
133 increment_region = True
135 if random_number > 1:
136 self.region_map[h][w] = self.region_map[h][w - 1]
138 self.region_map[h][w] = self.regions
139 increment_region = True
141 if random_number > 1:
142 self.region_map[h][w] = self.region_map[h - 1][w]
144 self.region_map[h][w] = self.regions
145 increment_region = True
147 if random_number > 1:
148 self.region_map[h][w] = self.region_map[h - 1][w]
150 elif random_number > 0:
151 self.region_map[h][w] = self.region_map[h][w - 1]
153 self.region_map[h][w] = self.regions
154 increment_region = True
160 self.rooms[-1].add_region([h,w])
162 def generate_tiles(self, region_selected):
164 :param region_selected:
167 for h in range(self.height):
168 for w in range(self.width):
169 if self.region_map[h][w] == region_selected:
171 w_dist = self.dist_from_other_rooms
172 elif self.region_map[h][w-1] == region_selected:
175 w_dist = self.dist_from_other_rooms
177 if w + 1 == self.width:
178 e_dist = self.region_size - self.dist_from_other_rooms
179 elif self.region_map[h][w+1] == region_selected:
180 e_dist = self.region_size
182 e_dist = self.region_size - self.dist_from_other_rooms
185 n_dist = self.dist_from_other_rooms
186 elif self.region_map[h-1][w] == region_selected:
189 n_dist = self.dist_from_other_rooms
191 if h + 1 == self.height:
192 s_dist = self.region_size - self.dist_from_other_rooms
193 elif self.region_map[h+1][w] == region_selected:
194 s_dist = self.region_size
196 s_dist = self.region_size - self.dist_from_other_rooms
198 for wt in range(w_dist, e_dist):
199 for ht in range(n_dist, s_dist):
200 self.map[h * self.region_size + ht]\
201 [w * self.region_size + wt] = ' '
203 def generate_passage_tiles(self):
204 """ Generate the tiles that form the passages between the rooms
211 file = open('map.txt', 'w')
214 file.write(''.join(l))
217 for l in self.region_map:
221 if __name__ == '__main__':
223 level = LevelGenerator(width=4, height=3, no_rooms=4,
224 min_room_size=5, max_room_size=20,
225 dist_from_edge=1, dist_from_other_rooms=1,
229 input("Press Enter to continue...")