From 3f374d2558ba46963d3638fb0479db11139fffa0 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Tue, 10 Nov 2020 21:41:54 +0100 Subject: [PATCH] Spawn a random amount of squirrels on the map --- dungeonbattle/game.py | 2 ++ dungeonbattle/interfaces.py | 40 +++++++++++++++++++++----- dungeonbattle/tests/interfaces_test.py | 2 +- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/dungeonbattle/game.py b/dungeonbattle/game.py index 3dc60cc..c393602 100644 --- a/dungeonbattle/game.py +++ b/dungeonbattle/game.py @@ -1,4 +1,5 @@ import sys +from random import randint from typing import Any from .entities.player import Player @@ -51,6 +52,7 @@ class Game: self.player = Player() self.player.move(1, 6) self.map.add_entity(self.player) + self.map.spawn_random_entities(randint(1, 5)) @staticmethod def load_game(filename: str) -> None: diff --git a/dungeonbattle/interfaces.py b/dungeonbattle/interfaces.py index bbcd25e..a0c39dc 100644 --- a/dungeonbattle/interfaces.py +++ b/dungeonbattle/interfaces.py @@ -1,5 +1,7 @@ #!/usr/bin/env python from enum import Enum, auto +from random import randint +from typing import List from dungeonbattle.display.texturepack import TexturePack @@ -11,7 +13,7 @@ class Map: """ width: int height: int - tiles: list + tiles: List[List["Tile"]] # coordinates of the point that should be # on the topleft corner of the screen currentx: int @@ -30,8 +32,16 @@ class Map: self.entities.append(entity) entity.map = self + def is_free(self, y: int, x: int) -> bool: + """ + Indicates that the case at the coordinates (y, x) is empty. + """ + return 0 <= y < self.height and 0 <= x < self.width and \ + self.tiles[y][x].can_walk() and \ + not any(entity.x == x and entity.y == y for entity in self.entities) + @staticmethod - def load(filename: str): + def load(filename: str) -> "Map": """ Read a file that contains the content of a map, and build a Map object. """ @@ -40,7 +50,7 @@ class Map: return Map.load_from_string(file) @staticmethod - def load_from_string(content: str): + def load_from_string(content: str) -> "Map": """ Load a map represented by its characters and build a Map object. """ @@ -61,6 +71,22 @@ class Map: return "\n".join("".join(tile.char(pack) for tile in line) for line in self.tiles) + def spawn_random_entities(self, count: int) -> None: + """ + Put randomly {count} squirrels on the map, where it is available. + """ + for _ in range(count): + y, x = 0, 0 + while True: + y, x = randint(0, self.height - 1), randint(0, self.width - 1) + tile = self.tiles[y][x] + if tile.can_walk(): + break + from dungeonbattle.entities.monsters import Squirrel + squirrel = Squirrel() + squirrel.move(y, x) + self.add_entity(squirrel) + class Tile(Enum): EMPTY = auto() @@ -84,7 +110,7 @@ class Tile(Enum): """ Check if an entity (player or not) can move in this tile. """ - return not self.is_wall() + return not self.is_wall() and self != Tile.EMPTY class Entity: @@ -99,10 +125,10 @@ class Entity: def check_move(self, y: int, x: int, move_if_possible: bool = False)\ -> bool: - tile = self.map.tiles[y][x] - if tile.can_walk() and move_if_possible: + free = self.map.is_free(y, x) + if free and move_if_possible: self.move(y, x) - return tile.can_walk() + return free def move(self, y: int, x: int) -> None: self.y = y diff --git a/dungeonbattle/tests/interfaces_test.py b/dungeonbattle/tests/interfaces_test.py index c36e895..c82083c 100644 --- a/dungeonbattle/tests/interfaces_test.py +++ b/dungeonbattle/tests/interfaces_test.py @@ -31,5 +31,5 @@ class TestInterfaces(unittest.TestCase): self.assertFalse(Tile.EMPTY.is_wall()) self.assertTrue(Tile.FLOOR.can_walk()) self.assertFalse(Tile.WALL.can_walk()) - self.assertTrue(Tile.EMPTY.can_walk()) + self.assertFalse(Tile.EMPTY.can_walk()) self.assertRaises(ValueError, Tile.from_ascii_char, 'unknown')