from random import choice, random, randint from dungeonbattle.interfaces import Map, Tile class Generator: def __init__(self, params): self.params = params def run(self): width, height = self.params["width"], self.params["height"] walkers = [Walker(width//2, height//2)] grid = [[Tile.WALL] * width] * height count = 0 while count < self.params["fill"] * width*height: # because we can't add or remove walkers while looping over the pop # we need lists to keep track of what will be the walkers for the # next iteration of the main loop next_walker_pop = [] for walker in walkers: if grid[walker.y][walker.x] == Tile.WALL: count += 1 grid[walker.y][walker.x] = Tile.EMPTY if random() < self.params["turn_chance"]: walker.random_turn() walker.move_in_bounds(width, height) if random() > self.params["death_chance"]: next_walker_pop.append(walker) # we use a second loop for spliting so we're not bothered by cases # like a walker not spliting because we hit the population cap even # though the next one would have died and freed a place # not a big if it happened though for walker in walkers: if len(next_walker_pop) < self.params["max_walkers"]: if random() < self.params["split_chance"]: next_walker_pop.append(walker.split()) walkers = next_walker_pop start_x, start_y = randint(0, width), randint(0, height) while grid[start_y][start_x] != Tile.EMPTY: start_x, start_y = randint(0, width), randint(0, height) return Map(width, height, grid, start_x, start_y)