diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index e4544b0..bb917ec 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -12,7 +12,7 @@ import sys from .entities.player import Player from .enums import GameMode, KeyValues, DisplayActions from .interfaces import Map, Logs -from .mapgeneration import randomwalk, broguelike +from .mapgeneration import broguelike from .resources import ResourceManager from .settings import Settings from . import menus diff --git a/squirrelbattle/mapgeneration/randomwalk.py b/squirrelbattle/mapgeneration/randomwalk.py deleted file mode 100644 index 419d342..0000000 --- a/squirrelbattle/mapgeneration/randomwalk.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse -# SPDX-License-Identifier: GPL-3.0-or-later - -from enum import auto, Enum -from random import choice, random, randint -from typing import Tuple - -from ..interfaces import Map, Tile - - -DEFAULT_PARAMS = { - "split_chance": .15, - "turn_chance": .5, - "death_chance": .1, - "max_walkers": 15, - "width": 100, - "height": 100, - "fill": .4, - "no_lone_walls": False, -} - - -class Directions(Enum): - up = auto() - down = auto() - left = auto() - right = auto() - - -class Walker: - def __init__(self, x: int, y: int): - self.x = x - self.y = y - self.dir = choice(list(Directions)) - - def random_turn(self) -> None: - self.dir = choice(list(Directions)) - - def next_pos(self) -> Tuple[int, int]: - if self.dir == Directions.up: - return self.x, self.y + 1 - elif self.dir == Directions.down: - return self.x, self.y - 1 - elif self.dir == Directions.right: - return self.x + 1, self.y - elif self.dir == Directions.left: - return self.x - 1, self.y - - def move_in_bounds(self, width: int, height: int) -> None: - nx, ny = self.next_pos() - if 0 < nx < width-1 and 0 < ny < height-1: - self.x, self.y = nx, ny - - def split(self) -> "Walker": - child = Walker(self.x, self.y) - child.dir = self.dir - return child - - -class Generator: - def __init__(self, params: dict = DEFAULT_PARAMS): - self.params = params - - def run(self) -> Map: - width, height = self.params["width"], self.params["height"] - walkers = [Walker(width // 2, height // 2)] - grid = [[Tile.EMPTY for _ in range(width)] for _ in range(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.EMPTY: - count += 1 - grid[walker.y][walker.x] = Tile.FLOOR - 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 make sure to never kill all walkers - if not next_walker_pop: - next_walker_pop.append(choice(walkers)) - - # 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 = -1, -1 - while grid[start_y][start_x] != Tile.FLOOR or start_x == -1: - start_x, start_y = randint(0, width - 1), randint(0, height - 1) - - result = Map(width, height, grid, start_y, start_x) - - # post-processing: add walls - for x in range(width): - for y in range(height): - if grid[y][x] == Tile.EMPTY: - c = sum([1 if grid[j][i] == Tile.FLOOR else 0 for j, i in Map.neighbourhood(grid, y, x)]) - if c == 4 and self.params["no_lone_walls"]: - result.tiles[y][x] = Tile.FLOOR - elif c > 0: - result.tiles[y][x] = Tile.WALL - for x in range(width): - for y in [0, height-1]: - if grid[y][x] == Tile.FLOOR: - grid[y][x] = Tile.WALL - for y in range(height): - for x in [0, width-1]: - if grid[y][x] == Tile.FLOOR: - grid[y][x] = Tile.WALL - - return result diff --git a/squirrelbattle/tests/mapgeneration_test.py b/squirrelbattle/tests/mapgeneration_test.py index 85d1722..062b2e0 100644 --- a/squirrelbattle/tests/mapgeneration_test.py +++ b/squirrelbattle/tests/mapgeneration_test.py @@ -5,7 +5,7 @@ import unittest from random import randint from squirrelbattle.interfaces import Map, Tile -from squirrelbattle.mapgeneration import randomwalk, broguelike +from squirrelbattle.mapgeneration import broguelike def is_connex(grid): h, w = len(grid), len(grid[0]) @@ -20,29 +20,10 @@ def is_connex(grid): queue += Map.neighbourhood(grid, y, x) return not(any([any([t.can_walk() for t in l]) for l in grid])) -class TestRandomWalk(unittest.TestCase): - def setUp(self) -> None: - #we set no_lone_walls to true for 100% coverage - params = randomwalk.DEFAULT_PARAMS - params["no_lone_walls"] = True - self.generator = randomwalk.Generator(params = params) - - def test_starting(self) -> None: - """ - Create a map and check that the whole map is accessible from the starting position using a - depth-first search - """ - m = self.generator.run() - self.assertTrue(m.tiles[m.start_y][m.start_x].can_walk()) - - def test_connexity(self) -> None: - m = self.generator.run() - self.assertTrue(is_connex(m.tiles)) - class TestBroguelike(unittest.TestCase): def setUp(self) -> None: self.generator = broguelike.Generator() - + def test_connexity(self) -> None: m = self.generator.run() self.assertTrue(is_connex(m.tiles))