<조건>
-CA(Cellular Automata)를 이용하여 동굴형태의 던전맵을 생성.
-0세대(랜덤생성맵) Wall의 생성 비율은 45%, 5세대까지 Loop.
-경계면도 Rule 적용.
-Rule은 B5678/S45678
-Moore neighborhood 검색방식.
<결과 예제: 40x20 크기로 5세대까지 Loop>
<소스코드>
# -*- coding: utf-8 -*- # # cave_map_generator.py # # http://codememo.tistory.com # # # - Wall / Space - Empty, CA Rule - B5678/S45678 # import sys import os import random class Map: wall_ratio = 45 def __init__(self, column, row): self.column, self.row = column, row self.wall, self.empty = 0, 0 self.map = [["#"] * self.row for m in range(self.column)] self.new_map = [["#"] * self.row for m in range(self.column)] for column in range(self.column): for row in range(self.row): if (0< row < self.row - 1) and (0 < column < self.column - 1): if (random.random() * 100) < self.wall_ratio: self.map[column][row] = "#" else: self.map[column][row] = " " self.new_map[column][row] = " " print("0 Generation") self.result() def generate(self, count): for i in range(1, count + 1): for column in range(1, self.column - 1): for row in range(1, self.row -1): self.check(column, row) print("%d Generation" % (i)) self.map = self.new_map self.result() self.new_map = [["#"] * self.row for m in range(self.column)] for m in range(1, self.column - 1): for n in range(1, self.row - 1): self.new_map[m][n] = " " def check(self, column, row): neighborhood_empty, neighborhood_wall = 0, 0 for m in range(-1, 2): for n in range(-1, 2): if m != 0 or n != 0: if self.map[column + m][row + n] == "#": neighborhood_wall += 1 elif self.map[column + m][row + n] == " ": neighborhood_empty += 1 if ((self.map[column][row] == "#" and neighborhood_wall >= 4) or (self.map[column][row] == " " and neighborhood_wall >= 5)): self.new_map[column][row] = "#" else: self.new_map[column][row] = " " def result(self): dungeon = "" self.wall, self.empty = 0, 0 for column in range(self.column): for row in range(self.row): dungeon += self.map[column][row] if self.map[column][row] == "#": self.wall += 1 else: self.empty += 1 if column < (self.column - 1): dungeon += "\n" print("Wall : %d Empty: %d" % (self.wall, self.empty)) print(dungeon) def main(): map = Map(20, 40) map.generate(5) sys.exit() if __name__ == "__main__": main()
<참고>