Add map generator
[koperkapel.git] / koperkapel / generators / maps.py
1 """ Procedural map generation for levels """
2
3 import random
4 import math
5
6 i = random.randint(0,100)
7
8
9 class LevelGenerator:
10     width = 0
11     height = 0
12     rooms = 0
13     map = None
14     min_room_size = 0
15     max_room_size = 0
16     dist_from_edge = 0
17     dist_from_other_rooms = 0
18     regions = None
19     region = 0
20     region_size_in_tiles = 0
21
22     def __init__(self, width, height, rooms, min_room_size, max_room_size, dist_from_edge,
23                  dist_from_other_rooms, region_size_in_tiles):
24         """ Initialize the level parameters
25         """
26         self.width = width
27         self.height = height
28         self.rooms = rooms
29         self.min_room_size = min_room_size
30         self.max_room_size = max_room_size
31         self.dist_from_edge = dist_from_edge
32         self.dist_from_other_rooms = dist_from_other_rooms
33         self.region_size_in_tiles = region_size_in_tiles
34
35     def generate(self):
36         """ Generate a random level map
37         """
38         self.generate_regions()
39         row = ['#' for x in range(self.width * self.region_size_in_tiles)]
40         self.map = [row[:] for x in range(self.height * self.region_size_in_tiles)]
41         regions_selected = random.sample(range(self.region), min(self.region, self.rooms))
42         print('Regions: %s' % str(regions_selected))
43         for region in regions_selected:
44             self.generate_room(region)
45
46     def generate_regions(self):
47         """ Generate a random level region map
48         """
49         row = ['#' for x in range(self.width)]
50         self.regions = [row[:] for x in range(self.height)]
51         for h in range(self.height):
52             for w in range(self.width):
53                 random_number = random.randint(0, 2)
54                 if w == h == 0:
55                     self.regions[h][w] = self.region
56                     self.region += 1
57                 elif h == 0:
58                     if random_number > 1:
59                         try:
60                             self.regions[h][w] = self.regions[h][w - 1]
61                         except:
62                             print(h, w)
63                             raise
64                     else:
65                         self.regions[h][w] = self.region
66                         self.region += 1
67                 elif w == 0:
68                     if random_number > 1:
69                         self.regions[h][w] = self.regions[h - 1][w]
70                     else:
71                         self.regions[h][w] = self.region
72                         self.region += 1
73                 else:
74                     if random_number > 1:
75                         self.regions[h][w] = self.regions[h - 1][w]
76                     elif random_number > 0:
77                         self.regions[h][w] = self.regions[h][w - 1]
78                     else:
79                         self.regions[h][w] = self.region
80                         self.region += 1
81
82     def generate_room(self, region_selected):
83         """
84         """
85         for h in range(self.height):
86             for w in range(self.width):
87                 if self.regions[h][w] == region_selected:
88                     if w == 0:
89                         w_dist = self.dist_from_other_rooms
90                     elif self.regions[h][w-1] == region_selected:
91                         w_dist = 0
92                     else:
93                         w_dist = self.dist_from_other_rooms
94
95                     if w + 1 == self.width:
96                         e_dist = self.region_size_in_tiles - self.dist_from_other_rooms
97                     elif self.regions[h][w+1] == region_selected:
98                         e_dist = self.region_size_in_tiles
99                     else:
100                         e_dist = self.region_size_in_tiles - self.dist_from_other_rooms
101
102                     if h == 0:
103                         n_dist = self.dist_from_other_rooms
104                     elif self.regions[h-1][w] == region_selected:
105                         n_dist = 0
106                     else:
107                         n_dist = self.dist_from_other_rooms
108
109                     if h + 1 == self.height:
110                         s_dist = self.region_size_in_tiles - self.dist_from_other_rooms
111                     elif self.regions[h+1][w] == region_selected:
112                         s_dist = self.region_size_in_tiles
113                     else:
114                         s_dist = self.region_size_in_tiles - self.dist_from_other_rooms
115
116                     for wt in range(w_dist, e_dist):
117                         for ht in range(n_dist, s_dist):
118                             self.map[h * self.region_size_in_tiles + ht][w * self.region_size_in_tiles + wt] = ' '
119
120     def display(self):
121         file = open('map.txt', 'w')
122         for l in self.map:
123             print(''.join(l))
124             file.write(''.join(l))
125             file.write('\n')
126         file.close()
127         for l in self.regions:
128             print(l)
129
130
131 if __name__ == '__main__':
132     while True:
133         level = LevelGenerator(width=8, height=5, rooms=12, min_room_size=5, max_room_size=20,
134                                dist_from_edge=2, dist_from_other_rooms=1, region_size_in_tiles=6)
135         level.generate()
136         level.display()
137         input("Press Enter to continue...")