Added documentation on a lot of classes and functions (and removed some files I commited by mistake)

This commit is contained in:
eichhornchen 2020-11-18 12:19:27 +01:00 committed by Yohann D'ANELLO
parent 41d1696c9b
commit 8f932604f6
5 changed files with 126 additions and 33 deletions

View File

@ -4,6 +4,11 @@ from dungeonbattle.term_manager import TermManager
class Bootstrap:
"""
The bootstrap object is used to bootstrap the game so that it starts properly.
(It was initially created to avoid circulary imports between the Game and
Display classes)
"""
@staticmethod
def run_game():

View File

@ -3,13 +3,22 @@ from typing import Optional
from dungeonbattle.settings import Settings
#This file contains a few useful enumeration classes used elsewhere in the code
class DisplayActions(Enum):
"""
Display actions options for the callable displayaction Game uses
(it just calls the same action on the display object displayaction refers to)
"""
REFRESH = auto()
UPDATE = auto()
class GameMode(Enum):
"""
Game mode options
"""
MAINMENU = auto()
PLAY = auto()
SETTINGS = auto()
@ -17,6 +26,9 @@ class GameMode(Enum):
class KeyValues(Enum):
"""
Key values options used in the game
"""
UP = auto()
DOWN = auto()
LEFT = auto()

View File

@ -12,6 +12,9 @@ from typing import Callable
class Game:
"""
The game object controls all actions in the game.
"""
map: Map
player: Player
# display_actions is a display interface set by the bootstrapper
@ -43,8 +46,8 @@ class Game:
def run(self, screen: Any) -> None:
"""
Main infinite loop.
We wait for a player action, then we do what that should be done
when the given key got pressed.
We wait for the player's action, then we do what that should be done
when the given key gets pressed.
"""
while True: # pragma no cover
screen.clear()
@ -70,7 +73,7 @@ class Game:
def handle_key_pressed_play(self, key: KeyValues) -> None:
"""
In play mode, arrows or zqsd should move the main character.
In play mode, arrows or zqsd move the main character.
"""
if key == KeyValues.UP:
if self.player.move_up():
@ -108,15 +111,16 @@ class Game:
elif option == menus.MainMenuValues.EXIT:
sys.exit(0)
def game_to_str(self) -> str:
d = dict()
d["Map"] = game.map
d["Player"] = game.player
def save_state(self) -> dict():
"""
Saves the game to a dictionnary
"""
return self.map.save_state()
def load_state(self, d: dict) -> None:
"""
Loads the game from a dictionnary
"""
self.map.load_state(d)
def load_game(self) -> None:
@ -129,7 +133,7 @@ class Game:
def save_game(self) -> None:
"""
Save the game to a file
Saves the game to a file
"""
with open("save.json", "w") as f:
f.write(json.dumps(self.save_state()))

View File

@ -10,7 +10,7 @@ from dungeonbattle.display.texturepack import TexturePack
class Map:
"""
Object that represents a Map with its width, height
and the whole tiles, with their custom properties.
and tiles, that have their custom properties.
"""
width: int
height: int
@ -120,6 +120,9 @@ class Map:
entity.act(self)
def save_state(self) -> dict:
"""
Saves the map's attributes to a dictionnary
"""
d = dict()
d["width"] = self.width
d["height"] = self.height
@ -133,6 +136,9 @@ class Map:
return d
def load_state(self, d: dict) -> None:
"""
Loads the map's attributes from a dictionnary
"""
self.width = d["width"]
self.height = d["height"]
self.start_y = d["start_y"]
@ -143,6 +149,9 @@ class Map:
#add entities
class Tile(Enum):
"""
The internal representation of the tiles of the map
"""
EMPTY = auto()
WALL = auto()
FLOOR = auto()
@ -158,9 +167,15 @@ class Tile(Enum):
raise ValueError(ch)
def char(self, pack: TexturePack) -> str:
"""
Translates a Tile to the corresponding character according to the texture pack
"""
return getattr(pack, self.name)
def is_wall(self) -> bool:
"""
Is this Tile a wall?
"""
return self == Tile.WALL
def can_walk(self) -> bool:
@ -171,10 +186,13 @@ class Tile(Enum):
class Entity:
"""
An Entity object represents any entity present on the map
"""
y: int
x: int
name: str
map: Map
map: Map
def __init__(self):
self.y = 0
@ -182,29 +200,47 @@ class Entity:
def check_move(self, y: int, x: int, move_if_possible: bool = False)\
-> bool:
"""
Checks if moving to (y,x) is authorized
"""
free = self.map.is_free(y, x)
if free and move_if_possible:
self.move(y, x)
return free
def move(self, y: int, x: int) -> bool:
"""
Moves an entity to (y,x) coordinates
"""
self.y = y
self.x = x
return True
def move_up(self, force: bool = False) -> bool:
"""
Moves the entity up one tile, if possible
"""
return self.move(self.y - 1, self.x) if force else \
self.check_move(self.y - 1, self.x, True)
def move_down(self, force: bool = False) -> bool:
"""
Moves the entity down one tile, if possible
"""
return self.move(self.y + 1, self.x) if force else \
self.check_move(self.y + 1, self.x, True)
def move_left(self, force: bool = False) -> bool:
"""
Moves the entity left one tile, if possible
"""
return self.move(self.y, self.x - 1) if force else \
self.check_move(self.y, self.x - 1, True)
def move_right(self, force: bool = False) -> bool:
"""
Moves the entity right one tile, if possible
"""
return self.move(self.y, self.x + 1) if force else \
self.check_move(self.y, self.x + 1, True)
@ -229,14 +265,23 @@ class Entity:
return sqrt(self.distance_squared(other))
def is_fighting_entity(self) -> bool:
"""
Is this entity a fighting entity?
"""
return isinstance(self, FightingEntity)
def is_item(self) -> bool:
"""
Is this entity an item?
"""
from dungeonbattle.entities.items import Item
return isinstance(self, Item)
@staticmethod
def get_all_entity_classes():
"""
Returns all entities subclasses
"""
from dungeonbattle.entities.items import Heart, Bomb
from dungeonbattle.entities.monsters import Beaver, Hedgehog, \
Rabbit, TeddyBear
@ -260,6 +305,10 @@ class Entity:
class FightingEntity(Entity):
"""
A FightingEntity is an entity that can fight, and thus has a health,
level and stats
"""
maxhealth: int
health: int
strength: int
@ -285,27 +334,45 @@ class FightingEntity(Entity):
def hit(self, opponent: "FightingEntity") -> None:
"""
Deals damage to the opponent, based on the stats
"""
opponent.take_damage(self, self.strength)
def take_damage(self, attacker: "Entity", amount: int) -> None:
"""
Take damage from the attacker, based on the stats
"""
self.health -= amount
if self.health <= 0:
self.die()
def die(self) -> None:
"""
If a fighting entity has no more health, it dies and is removed
"""
self.dead = True
self.map.remove_entity(self)
def keys(self) -> list:
"""
Returns a fighting entities specific attributes
"""
return ["maxhealth", "health", "level", "dead", "strength", "intelligence", "charisma", "dexterity", "constitution"]
def save_state(self) -> dict:
"""
Saves the state of the entity into a dictionnary
"""
d = super().save_state()
for name in self.keys():
d[name] = self.__getattribute__(name)
return d
def recover_state(self, d : dict) -> None:
"""
Loads the state of an entity from a dictionnary
"""
super().recover_state(d)
for name in d.keys():
self.__setattribute__(name, d[name])

View File

@ -8,24 +8,41 @@ from .settings import Settings
class Menu:
"""
A Menu object is the logical representation of a menu in the game
"""
values: list
def __init__(self):
self.position = 0
def go_up(self) -> None:
"""
Moves the pointer of the menu on the previous value
"""
self.position = max(0, self.position - 1)
def go_down(self) -> None:
"""
Moves the pointer of the menu on the next value
"""
self.position = min(len(self.values) - 1, self.position + 1)
def validate(self) -> Any:
"""
Selects the value that is pointed by the menu pointer
"""
return self.values[self.position]
class MainMenuValues(Enum):
"""
Values of the main menu
"""
START = 'Nouvelle partie'
RESUME = 'Continuer'
SAVE = 'Sauvegarder'
LOAD = 'Charger'
SETTINGS = 'Paramètres'
EXIT = 'Quitter'
@ -34,34 +51,22 @@ class MainMenuValues(Enum):
class MainMenu(Menu):
"""
A special instance of a menu : the main menu
"""
values = [e for e in MainMenuValues]
def handle_key_pressed(self, key: KeyValues, game: Any) -> None:
"""
In the main menu, we can navigate through options.
"""
if key == KeyValues.DOWN:
self.go_down()
if key == KeyValues.UP:
self.go_up()
if key == KeyValues.ENTER:
option = self.validate()
if option == MainMenuValues.START:
game.new_game()
game.state = GameMode.PLAY
game.display_actions(DisplayActions.UPDATE)
elif option == MainMenuValues.RESUME:
game.state = GameMode.PLAY
elif option == MainMenuValues.SETTINGS:
game.state = GameMode.SETTINGS
elif option == MainMenuValues.EXIT:
sys.exit(0)
class SettingsMenu(Menu):
"""
A special instance of a menu : the settings menu
"""
waiting_for_key: bool = False
def update_values(self, settings: Settings) -> None:
"""
The settings can change, so they are updated
"""
self.values = []
for i, key in enumerate(settings.settings_keys):
s = settings.get_comment(key)
@ -81,7 +86,7 @@ class SettingsMenu(Menu):
def handle_key_pressed(self, key: Optional[KeyValues], raw_key: str,
game: Any) -> None:
"""
Update settings
In the setting menu, we van select a setting and change it
"""
if not self.waiting_for_key:
# Navigate normally through the menu.