Add map generator
authorDavid Sharpe <decoydavid@gmail.com>
Sun, 28 Feb 2016 21:43:07 +0000 (23:43 +0200)
committerDavid Sharpe <decoydavid@gmail.com>
Sun, 28 Feb 2016 21:43:07 +0000 (23:43 +0200)
koperkapel/generators/__init__.py [new file with mode: 0644]
koperkapel/generators/maps.py [new file with mode: 0644]

diff --git a/koperkapel/generators/__init__.py b/koperkapel/generators/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/koperkapel/generators/maps.py b/koperkapel/generators/maps.py
new file mode 100644 (file)
index 0000000..6f62b0b
--- /dev/null
@@ -0,0 +1,137 @@
+""" Procedural map generation for levels """
+
+import random
+import math
+
+i = random.randint(0,100)
+
+
+class LevelGenerator:
+    width = 0
+    height = 0
+    rooms = 0
+    map = None
+    min_room_size = 0
+    max_room_size = 0
+    dist_from_edge = 0
+    dist_from_other_rooms = 0
+    regions = None
+    region = 0
+    region_size_in_tiles = 0
+
+    def __init__(self, width, height, rooms, min_room_size, max_room_size, dist_from_edge,
+                 dist_from_other_rooms, region_size_in_tiles):
+        """ Initialize the level parameters
+        """
+        self.width = width
+        self.height = height
+        self.rooms = rooms
+        self.min_room_size = min_room_size
+        self.max_room_size = max_room_size
+        self.dist_from_edge = dist_from_edge
+        self.dist_from_other_rooms = dist_from_other_rooms
+        self.region_size_in_tiles = region_size_in_tiles
+
+    def generate(self):
+        """ Generate a random level map
+        """
+        self.generate_regions()
+        row = ['#' for x in range(self.width * self.region_size_in_tiles)]
+        self.map = [row[:] for x in range(self.height * self.region_size_in_tiles)]
+        regions_selected = random.sample(range(self.region), min(self.region, self.rooms))
+        print('Regions: %s' % str(regions_selected))
+        for region in regions_selected:
+            self.generate_room(region)
+
+    def generate_regions(self):
+        """ Generate a random level region map
+        """
+        row = ['#' for x in range(self.width)]
+        self.regions = [row[:] for x in range(self.height)]
+        for h in range(self.height):
+            for w in range(self.width):
+                random_number = random.randint(0, 2)
+                if w == h == 0:
+                    self.regions[h][w] = self.region
+                    self.region += 1
+                elif h == 0:
+                    if random_number > 1:
+                        try:
+                            self.regions[h][w] = self.regions[h][w - 1]
+                        except:
+                            print(h, w)
+                            raise
+                    else:
+                        self.regions[h][w] = self.region
+                        self.region += 1
+                elif w == 0:
+                    if random_number > 1:
+                        self.regions[h][w] = self.regions[h - 1][w]
+                    else:
+                        self.regions[h][w] = self.region
+                        self.region += 1
+                else:
+                    if random_number > 1:
+                        self.regions[h][w] = self.regions[h - 1][w]
+                    elif random_number > 0:
+                        self.regions[h][w] = self.regions[h][w - 1]
+                    else:
+                        self.regions[h][w] = self.region
+                        self.region += 1
+
+    def generate_room(self, region_selected):
+        """
+        """
+        for h in range(self.height):
+            for w in range(self.width):
+                if self.regions[h][w] == region_selected:
+                    if w == 0:
+                        w_dist = self.dist_from_other_rooms
+                    elif self.regions[h][w-1] == region_selected:
+                        w_dist = 0
+                    else:
+                        w_dist = self.dist_from_other_rooms
+
+                    if w + 1 == self.width:
+                        e_dist = self.region_size_in_tiles - self.dist_from_other_rooms
+                    elif self.regions[h][w+1] == region_selected:
+                        e_dist = self.region_size_in_tiles
+                    else:
+                        e_dist = self.region_size_in_tiles - self.dist_from_other_rooms
+
+                    if h == 0:
+                        n_dist = self.dist_from_other_rooms
+                    elif self.regions[h-1][w] == region_selected:
+                        n_dist = 0
+                    else:
+                        n_dist = self.dist_from_other_rooms
+
+                    if h + 1 == self.height:
+                        s_dist = self.region_size_in_tiles - self.dist_from_other_rooms
+                    elif self.regions[h+1][w] == region_selected:
+                        s_dist = self.region_size_in_tiles
+                    else:
+                        s_dist = self.region_size_in_tiles - self.dist_from_other_rooms
+
+                    for wt in range(w_dist, e_dist):
+                        for ht in range(n_dist, s_dist):
+                            self.map[h * self.region_size_in_tiles + ht][w * self.region_size_in_tiles + wt] = ' '
+
+    def display(self):
+        file = open('map.txt', 'w')
+        for l in self.map:
+            print(''.join(l))
+            file.write(''.join(l))
+            file.write('\n')
+        file.close()
+        for l in self.regions:
+            print(l)
+
+
+if __name__ == '__main__':
+    while True:
+        level = LevelGenerator(width=8, height=5, rooms=12, min_room_size=5, max_room_size=20,
+                               dist_from_edge=2, dist_from_other_rooms=1, region_size_in_tiles=6)
+        level.generate()
+        level.display()
+        input("Press Enter to continue...")