From 9fe7846f1b2072081b9938b5f30d562b4ce1cd9d Mon Sep 17 00:00:00 2001 From: Suguivy Date: Mon, 13 Mar 2023 19:46:29 +0100 Subject: [PATCH] revised some code --- .gitignore | 2 +- actions.py | 2 +- entity.py | 7 ++--- floor.py | 28 +++++++++++------- game.py | 87 ++++++++++++++++++++++++++++++++---------------------- log.log | 0 6 files changed, 73 insertions(+), 53 deletions(-) delete mode 100644 log.log diff --git a/.gitignore b/.gitignore index 00e71b2..f1f1467 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -log.txt +*.log ideas.md __pycache__/ \ No newline at end of file diff --git a/actions.py b/actions.py index 6d9ebb8..23b7388 100644 --- a/actions.py +++ b/actions.py @@ -15,7 +15,7 @@ class NA: Action = Move | Idle | NA -action_timing = { +ACTION_TIMING = { Move: 50, Idle: 10, NA: 1 diff --git a/entity.py b/entity.py index 1d4b66d..0b784f2 100644 --- a/entity.py +++ b/entity.py @@ -1,4 +1,3 @@ -from enum import Enum from actions import Action, Idle, NA class Entity(): @@ -7,16 +6,16 @@ class Entity(): class Item(Entity): pass -class Character(Entity): +class Creature(Entity): def __init__(self): self.speed = 1 self.action: Action = NA() -class Player(Character): +class Player(Creature): def __init__(self): super().__init__() -class Enemy(Character): +class Enemy(Creature): def __init__(self): super().__init__() diff --git a/floor.py b/floor.py index 1cdf15c..9bc4b04 100644 --- a/floor.py +++ b/floor.py @@ -1,35 +1,38 @@ from enum import Enum from typing import Tuple -from entity import Character, Entity, Item +from entity import Creature, Item class TileType(Enum): + """ + An enum who has the different types of tiles + """ WALL = 1 AIR = 2 class EntityMap: """ - Class that stores entities in an special way in order to be able to reach in O(1) the values + A class that stores entities in an special way in order to be able to reach in O(1) the values """ def __init__(self): self.items = {} # K: Position V: List(Item) self.pos_creatures = {} # K: Position V: Creature self.creatures_pos = {} # K: Creature V: Position - def get_item(self, x, y): + def get_item(self, x, y) -> Item | None: return self.items.get((x, y)) - def get_creature(self, x, y): + def get_creature(self, x, y) -> Item | None: return self.pos_creatures.get((x, y)) - def get_creature_position(self, creature: Character): - return self.creatures_pos.get(creature) + def get_creature_position(self, creature: Creature) -> Tuple[int, int]: + return self.creatures_pos[creature] - def add_item(self, x, y, item: Item): + def add_item(self, x, y, item: Item) -> None: if (x, y) not in self.items: self.items[(x, y)] = [] self.items[(x, y)].append(item) - def add_creature(self, x, y, creature: Character) -> bool: + def add_creature(self, x, y, creature: Creature) -> bool: if (x, y) in self.pos_creatures: return False else: @@ -37,24 +40,27 @@ class EntityMap: self.creatures_pos[creature] = (x, y) return True - def pop_creature_pos(self, x, y) -> Character | None: + def pop_creature_pos(self, x, y) -> Creature | None: if (x, y) in self.pos_creatures: creature = self.pos_creatures.pop((x, y)) self.creatures_pos.pop(creature) return creature - def pop_creature_ref(self, creature: Character) -> Tuple[int, int] | None: + def pop_creature_ref(self, creature: Creature) -> Tuple[int, int] | None: if creature in self.creatures_pos: pos = self.creatures_pos.pop(creature) self.pos_creatures.pop(pos) return pos class Floor: + """ + A class that represents a specific floor of the dungeon + """ def __init__(self, width, height): self.width = width self.height = height self.grid = [[TileType.AIR] * height] * width self.entities = EntityMap() - def get_tile(self, x, y): + def get_tile(self, x, y) -> TileType: return self.grid[x][y] diff --git a/game.py b/game.py index f965a33..a98ab43 100644 --- a/game.py +++ b/game.py @@ -1,7 +1,8 @@ from terminal import Terminal -from entity import Character, Player, Item, Enemy +from entity import Creature, Player, Enemy from actions import * from floor import Floor, TileType +import sys TEXTURES = { TileType.WALL: '#', @@ -17,34 +18,52 @@ class Game: self.should_exit = False self.ticks = 0 self.schedule = {} + self.redirect_io('prints.log', 'errors.log') + + def __del__(self): + self.restore_io() + + def restore_io(self) -> None: + sys.stdout = self.stdout_original + sys.stderr = self.stderr_original + self.stdout_file.close() + self.stderr_file.close() + + def redirect_io(self, stdout_file, stderr_file) -> None: + self.stdout_original = sys.stdout + self.stderr_original = sys.stderr + self.stdout_file = open(stdout_file, 'w') + self.stderr_file = open(stderr_file, 'w') + sys.stdout = self.stdout_file + sys.stderr = self.stderr_file def run(self): """ Runs the game """ - self.instance_character(3, 3, self.player) + self.instance_creature(3, 3, self.player) self.render() while not self.should_exit: - action_was_performed = self.step() - if action_was_performed: + self.step() + if self.action_was_performed: self.render() - def instance_character(self, x, y, character: Character): + def instance_creature(self, x, y, creature: Creature): """ - Instances a character in space and time + Instances a creature in space and time """ - self.floor.entities.add_creature(x, y, character) - self.reschedule(character) + self.floor.entities.add_creature(x, y, creature) + self.reschedule(creature) - def reschedule(self, character: Character): + def reschedule(self, creature: Creature): """ - Calculates turns for the next avaliable ticks untill player turn + Calculates the ticks in which the creature will perform its next action """ - time = (action_timing[character.action.__class__] // character.speed) + self.ticks + time = (ACTION_TIMING[creature.action.__class__] // creature.speed) + self.ticks if self.schedule.get(time): - self.schedule[time].append(character) + self.schedule[time].append(creature) else: - self.schedule[time] = [character] + self.schedule[time] = [creature] def render(self): """ @@ -61,38 +80,34 @@ class Game: def step(self): """ - Perfoms a step in the game. Returns True if any creature did an action, and False otherwise + Perfoms a step in the game. Sets the `action_was_performed` attribute accordingly """ - creaturas = self.schedule.get(self.ticks) - if creaturas: - for creatura in creaturas: - if isinstance(creatura, Player): - self.get_event() - elif isinstance(creatura, Enemy): - creatura.calculate_action() - self.reschedule(creatura) - self.perform(creatura) + self.action_was_performed = False + creatures = self.schedule.get(self.ticks) + if creatures: + for creature in creatures: + if isinstance(creature, Player): + self.input_event() + elif isinstance(creature, Enemy): + creature.calculate_action() + self.reschedule(creature) + self.perform(creature) self.schedule.pop(self.ticks) - self.ticks += 1 - return True - else: - self.ticks += 1 - return False + self.action_was_performed = True + self.ticks += 1 - - def perform(self, character: Character): + def perform(self, creature: Creature): """ Performs an action for a creature """ - if isinstance(character.action, Move): - pos = self.floor.entities.pop_creature_ref(character) + if isinstance(creature.action, Move): + pos = self.floor.entities.pop_creature_ref(creature) if pos: - self.floor.entities.add_creature(pos[0] + character.action.x, pos[1] + character.action.y, character) + self.floor.entities.add_creature(pos[0] + creature.action.x, pos[1] + creature.action.y, creature) - - def get_event(self): + def input_event(self): """ - Waits for a game event to happen + Waits for a game event to happen, and behaves accordingly """ keycode = self.term.get_key() if keycode == "q": diff --git a/log.log b/log.log deleted file mode 100644 index e69de29..0000000