This commit is contained in:
Yohann D'ANELLO 2020-12-11 02:19:59 +01:00
parent 8751120fe1
commit 3c614dcca9
1 changed files with 29 additions and 23 deletions

View File

@ -1,15 +1,22 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later
from enum import auto, Enum from enum import auto, Enum
from random import choice, random, randint from random import choice, random, randint
from typing import Tuple
from ..interfaces import Map, Tile from ..interfaces import Map, Tile
DEFAULT_PARAMS = {"split_chance" : .15, DEFAULT_PARAMS = {
"turn_chance" : .5, "split_chance": .15,
"death_chance" : .1, "turn_chance": .5,
"max_walkers" : 15, "death_chance": .1,
"width" : 100, "max_walkers": 15,
"height" : 100, "width": 100,
"fill" : .4} "height": 100,
"fill": .4,
}
class Directions(Enum): class Directions(Enum):
@ -20,16 +27,15 @@ class Directions(Enum):
class Walker: class Walker:
def __init__(self, x: int, y: int):
def __init__(self, x, y):
self.x = x self.x = x
self.y = y self.y = y
self.dir = choice(list(Directions)) self.dir = choice(list(Directions))
def random_turn(self): def random_turn(self) -> None:
self.dir = choice(list(Directions)) self.dir = choice(list(Directions))
def next_pos(self): def next_pos(self) -> Tuple[int, int]:
if self.dir == Directions.up: if self.dir == Directions.up:
return self.x, self.y + 1 return self.x, self.y + 1
elif self.dir == Directions.down: elif self.dir == Directions.down:
@ -39,28 +45,29 @@ class Walker:
elif self.dir == Directions.left: elif self.dir == Directions.left:
return self.x - 1, self.y return self.x - 1, self.y
def move_in_bounds(self, width, height): def move_in_bounds(self, width: int, height: int) -> None:
nx, ny = self.next_pos() nx, ny = self.next_pos()
if 0 < nx < width and 0 < ny < height: if 0 < nx < width and 0 < ny < height:
self.x, self.y = nx, ny self.x, self.y = nx, ny
def split(self): def split(self) -> "Walker":
child = Walker(self.x, self.y) child = Walker(self.x, self.y)
child.dir = self.dir child.dir = self.dir
return child return child
class Generator: class Generator:
def __init__(self, params: dict = None):
def __init__(self, params = DEFAULT_PARAMS): if params is None:
params = DEFAULT_PARAMS
self.params = params self.params = params
def run(self): def run(self) -> Map:
width, height = self.params["width"], self.params["height"] width, height = self.params["width"], self.params["height"]
walkers = [Walker(width//2, height//2)] walkers = [Walker(width // 2, height // 2)]
grid = [[Tile.EMPTY for _ in range(width)] for _ in range(height)] grid = [[Tile.EMPTY for _ in range(width)] for _ in range(height)]
count = 0 count = 0
while count < self.params["fill"] * width*height: while count < self.params["fill"] * width * height:
# because we can't add or remove walkers while looping over the pop # 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 # we need lists to keep track of what will be the walkers for the
# next iteration of the main loop # next iteration of the main loop
@ -77,10 +84,10 @@ class Generator:
next_walker_pop.append(walker) next_walker_pop.append(walker)
# we make sure to never kill all walkers # we make sure to never kill all walkers
if next_walker_pop == []: if not next_walker_pop:
next_walker_pop.append(choice(walkers)) next_walker_pop.append(choice(walkers))
# we use a second loop for spliting so we're not bothered by cases # 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 # like a walker not spliting because we hit the population cap even
# though the next one would have died and freed a place # though the next one would have died and freed a place
# not a big if it happened though # not a big if it happened though
@ -90,9 +97,8 @@ class Generator:
next_walker_pop.append(walker.split()) next_walker_pop.append(walker.split())
walkers = next_walker_pop walkers = next_walker_pop
start_x, start_y = randint(0, width - 1), randint(0, height - 1)
start_x, start_y = randint(0, width-1), randint(0, height-1)
while grid[start_y][start_x] != Tile.FLOOR: while grid[start_y][start_x] != Tile.FLOOR:
start_x, start_y = randint(0, width-1), randint(0, height-1) start_x, start_y = randint(0, width - 1), randint(0, height - 1)
return Map(width, height, grid, start_x, start_y) return Map(width, height, grid, start_x, start_y)