45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
|
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)
|