diff --git a/labyrinth_engine/common_functions.py b/labyrinth_engine/common_functions.py index f033019..e22282c 100644 --- a/labyrinth_engine/common_functions.py +++ b/labyrinth_engine/common_functions.py @@ -1,2 +1,2 @@ -def from_module_name_to_path(module): +def from_module_name_to_path(module: str) -> str: return module.replace('.', '\\') diff --git a/labyrinth_engine/errors.py b/labyrinth_engine/errors.py index 16d8533..863c5b9 100644 --- a/labyrinth_engine/errors.py +++ b/labyrinth_engine/errors.py @@ -3,10 +3,10 @@ class LabyrinthError(Exception): class LabyrinthLoadError(LabyrinthError): - def __init__(self, msg): + def __init__(self, msg: str): self.msg = msg - def __str__(self): + def __str__(self) -> str: return 'File "{}"\n{}'.format(self.file, self.msg) # TODO: understand errors. to continue the list of errors. Issue #44 diff --git a/labyrinth_engine/labyrinth.py b/labyrinth_engine/labyrinth.py index 8aa6dfd..33d35e9 100644 --- a/labyrinth_engine/labyrinth.py +++ b/labyrinth_engine/labyrinth.py @@ -218,7 +218,7 @@ def get_active_player(self): return self.players_list[self.active_player_number] def get_active_player_username(self): - return self.get_active_player().get_username() if self.get_active_player() is not None else None + return self.get_active_player().get_username() def get_active_player_ats(self): """ @@ -247,10 +247,10 @@ def get_objects(self, lrtype=['location', 'item', 'player', 'creature'], class_n def save(self): save = { - 'seed': self.seed, - 'loadseed': self.loadseed, - 'users': list(map(lambda user: user.get_username(), self.players_list)), - 'turns': self.turns_log, + 'seed': self.seed, + 'loadseed': self.loadseed, + 'users': list(map(lambda user: user.get_username(), self.players_list)), + 'turns': self.turns_log } return json.dumps(save, indent=4, ensure_ascii=False) diff --git a/labyrinth_engine/labyrinth.pyi b/labyrinth_engine/labyrinth.pyi new file mode 100644 index 0000000..5cd4588 --- /dev/null +++ b/labyrinth_engine/labyrinth.pyi @@ -0,0 +1,78 @@ +from labyrinth_engine.labyrinth_object import AnyLO +from labyrinth_engine.lr_types import Location, Item, Player, Creature +from labyrinth_engine.ui_buttons import Button +from labyrinth_engine.ui_status_bars import Bar + +from typing import Any, Dict, Union, List, Callable, Set + + +class Labyrinth: + + seed: Union[int, Any] + loadseed: Union[int, Any] + imagepath: str + + unique_objects: Dict[str, AnyLO] + + locations: Set[Location] + items: Set[Item] + creatures: Set[Creature] + players_list: List[Player] + + to_send: Dict[int, Dict[str, List[str]]] + active_player_number: int + is_game_ended: bool + + turns_log: List[Dict[str, str]] + msgs_log: Dict[str, List[str]] + + MAX_COUNT_OF_SKIPS: int + + def __init__(self, + locations: List[Location], + items: List[Item], + creatures: List[Creature], + players: List[Player], + adjacence_list: Dict, + settings: Dict[str, Any], + imagepath: str, + seed: Union[int, Any], + loadseed: Union[int, Any]) -> None: ... + + # Сообщения. + def send_msg(self, msg: str, player: Player, priority: int = ...) -> None: ... + def clear_to_send(self) -> Dict[int, Dict[str, List[str]]]: ... + def regularize_to_send(self) -> Dict[str, List[str]]: ... + def player_to_send(self, username: str) -> List[str]: ... + def get_msgs(self, username: str) -> List[str]: ... + + # Уникальные предметы. + def set_unique(self, obj: AnyLO, key: str) -> None: ... + def get_unique(self, key: str) -> AnyLO: ... + + # Ход игрока. + def make_turn(self, turn: str) -> Dict[str, List[str]]: ... + def skip_turn(self) -> None: ... + def get_turns(self, number: Union[int, None] = ..., username: Union[str, None] = ...) -> Union[List[str], str]: ... + def end_game(self) -> None: ... + + # Активный игрок. + def get_next_active_player_number(self) -> Union[None, int]: ... + def get_next_active_player(self) -> Union[None, Player]: ... + def get_active_player(self) -> Player: ... + def get_active_player_username(self) -> str: ... + def get_active_player_ats(self) -> List[str]: ... + + # Объекты Лабиринта. + def get_all_objects(self) -> Set[AnyLO]: ... + def get_objects(self, + lrtype: Union[str, List[str]] = ..., + class_names: Union[str, List[str]] = ..., + flags: List[str] = ..., + key: Callable[[AnyLO], bool] = lambda x: True): ... + + def save(self) -> str: ... + + def get_buttons(self) -> List[Button]: ... + + def get_bars(self, username: str) -> List[Bar]: ... diff --git a/labyrinth_engine/labyrinth_object.py b/labyrinth_engine/labyrinth_object.py index f79c5a0..65ccc9b 100644 --- a/labyrinth_engine/labyrinth_object.py +++ b/labyrinth_engine/labyrinth_object.py @@ -1,4 +1,4 @@ -from labyrinth_engine.ui_buttons import CommonButton, DirectionButton, ListButton +from labyrinth_engine.ui_buttons import CommonButton, DirectionButton, ListButton from labyrinth_engine.ui_status_bars import StringBar @@ -7,7 +7,6 @@ class LabyrinthObject: LabyrinthObject is class of objects that can be used by players at their turns """ - labyrinth = None _lrtype = 'labyrinth_object' def __init__(self): @@ -65,7 +64,7 @@ def get_bars(self): # Родители, дети и т.д. def set_parent(self, parent): - if not (isinstance(parent, LabyrinthObject) or parent is None): + if not (isinstance(parent, LabyrinthObject)): raise ValueError( 'Invalid type of "parent" argument for LabyrinthObject.set_parent: ' + str(type(parent))) else: diff --git a/labyrinth_engine/labyrinth_object.pyi b/labyrinth_engine/labyrinth_object.pyi new file mode 100644 index 0000000..a16f675 --- /dev/null +++ b/labyrinth_engine/labyrinth_object.pyi @@ -0,0 +1,70 @@ +from labyrinth_engine.labyrinth import Labyrinth +from labyrinth_engine.lr_types import Location, Item, Player, Creature +from labyrinth_engine.ui_buttons import Button +from labyrinth_engine.ui_status_bars import Bar, StringBar + +from typing import Any, Dict, Union, List, Callable, TypeVar + +class LabyrinthObject: + labyrinth: Labyrinth + _lrtype: str + turn_set: Dict[str, Dict[str, Callable[[], Any]]] + flags: Dict[str: Any] + button_set: List[Button] + bar_set: List[Bar] + parent: Union[None, AnyLO] + name: str + + def __init__(self) -> None: ... + + # Предлагаемые игрокам ходы. + def new_at(self, function: Callable[[], None], condition: Callable[[], bool], turn_name: str) -> None: ... + def get_turns(self) -> Dict[str, Dict[str, Callable[[], Any]]]: ... + + # Флаги. + def set_flag(self, flag_name: str, arg: Any = ...) -> None: ... + def delete_flag(self, flag_name: str) -> Any: ... + def have_flag(self, flag_name: str) -> bool: ... + def get_flag(self, flag_name: str, default: Any = ...) -> Any: ... + + # Кнопки. + def new_button(self, turn: str, image: str): ... + def new_dbutton(self, turns: List[str], image: str): ... + def new_lbutton(self, turns: List[str], image: str, turn_images): ... + def get_buttons(self) -> List[Button]: ... + + # Бары. + def new_status_bar(self, name: str, init_value: Dict[Player, Any]) -> StringBar: ... + def get_bars(self) -> List[Bar]: ... + + # Родители, дети и т.д. + def set_parent(self, parent: AnyLO) -> None: ... + def get_parent(self) -> Union[None, AnyLO]: ... + def get_children(self, + lrtype: Union[str, List[str]] = ..., + class_names: Union[str, List[str]] = ..., + flags: List[str] = ..., + key: Callable[[AnyLO], bool] = ...): ... + + @property + def lrtype(self) -> str: + return self._lrtype + + def main(self) -> None: ... + + def set_settings(self, + settings: Dict[str, Any], + locations: List[Location], + items: List[Item], + creatures: List[Creature], + players: List[Player]) -> None: ... + + def get_name(self) -> str: ... + + def set_name(self, name: str) -> None: ... + + def __str__(self) -> str: ... + + def __repr__(self) -> str: ... + +AnyLO = TypeVar('AnyLO', bound=LabyrinthObject) diff --git a/labyrinth_engine/load_save.pyi b/labyrinth_engine/load_save.pyi new file mode 100644 index 0000000..e0d8d9c --- /dev/null +++ b/labyrinth_engine/load_save.pyi @@ -0,0 +1,8 @@ +from labyrinth_engine.labyrinth import Labyrinth +from typing import Any, Dict, Union, List + + +def load_save(save: Union[str, Dict[str, Union[int, List[str], List[Dict[str, str]]]]], _map: Union[str, Dict]) -> Labyrinth: ... + + +def load_map(_map: Union[str, Dict], users: List[str], loadseed: Union[int, Any] = ..., **kwargs) -> Labyrinth: ... diff --git a/labyrinth_engine/lr_types.py b/labyrinth_engine/lr_types.py index 17ebe16..6204fe9 100644 --- a/labyrinth_engine/lr_types.py +++ b/labyrinth_engine/lr_types.py @@ -17,7 +17,7 @@ def get_neighbour(self, direction): return self.directions[direction] def set_neighbour(self, direction, neighbour): - if not isinstance(neighbour, LO) or neighbour.lrtype != 'location': + if not isinstance(neighbour, Location): raise ValueError( 'Invalid "neighbour" argument for LabyrinthObject.set_neighbour: ' + str(neighbour)) else: diff --git a/labyrinth_engine/lr_types.pyi b/labyrinth_engine/lr_types.pyi new file mode 100644 index 0000000..2af16bd --- /dev/null +++ b/labyrinth_engine/lr_types.pyi @@ -0,0 +1,42 @@ +from labyrinth_engine import LabyrinthObject as LO + +from typing import Any, Dict, TypeVar + + +class Location(LO): + directions: Dict[str, AnyLocation] + + def get_neighbour(self, direction: str) -> AnyLocation: ... + + def set_neighbour(self, direction: str, neighbour: AnyLocation) -> Any: ... + +AnyLocation = TypeVar('AnyLocation', bound=Location) + + +class Item(LO): ... + +AnyItem = TypeVar('AnyItem', bound=Item) + + +class Player(LO): + name: str + username: str + + def __init__(self, username: str): ... + + def get_username(self) -> str: ... + + def set_turns_skip(self, count: int) -> None: ... + + def add_turns_skip(self, count: int) -> None: ... + + def die(self) -> None: ... + + def revive(self) -> None: ... + +AnyPlayer = TypeVar('AnyPlayer', bound=Player) + + +class Creature(LO): ... + +AnyCreature = TypeVar('AnyCreature', bound=Creature) \ No newline at end of file diff --git a/labyrinth_engine/ui_buttons.py b/labyrinth_engine/ui_buttons.py index 72e24d9..d45e3cc 100644 --- a/labyrinth_engine/ui_buttons.py +++ b/labyrinth_engine/ui_buttons.py @@ -2,6 +2,9 @@ class Button: def __str__(self): return ''.format(self.btn_type, ', '.join(self.turns)) + def get(self, *args, **kwargs): + pass + class CommonButton(Button): """ diff --git a/labyrinth_engine/ui_buttons.pyi b/labyrinth_engine/ui_buttons.pyi new file mode 100644 index 0000000..0b938c1 --- /dev/null +++ b/labyrinth_engine/ui_buttons.pyi @@ -0,0 +1,30 @@ +from typing import Any, Dict, Union, List + +class Button: + btn_type: str + turns: List[str] + image: str + + def __str__(self) -> str: ... + + def get(self, *args, **kwargs) -> Any: ... + + +class CommonButton(Button): + def __init__(self, turns: List[str], image: str) -> None: ... + + def get(self, ats: List[str], imagepath: str) -> Dict[str, Union[str, List[str]]]: ... + + +class DirectionButton(Button): + def __init__(self, turns: List[str], image: str) -> None: ... + + def get(self, ats: List[str], imagepath: str) -> Dict[str, Union[str, List[str]]]: ... + + +class ListButton(Button): + turn_images: List[str] + + def __init__(self, turns: List[str], image: str, turn_images: List[str]) -> None: ... + + def get(self, ats: List[str], imagepath: str) -> Dict[str, Union[str, List[str]]]: ... diff --git a/labyrinth_engine/ui_status_bars.py b/labyrinth_engine/ui_status_bars.py index 4632bc2..84a472b 100644 --- a/labyrinth_engine/ui_status_bars.py +++ b/labyrinth_engine/ui_status_bars.py @@ -2,6 +2,9 @@ class Bar: def __str__(self): return ''.format(self.bar_type, self.name) + def get(self, *args, **kwargs): + pass + class StringBar(Bar): """ diff --git a/labyrinth_engine/ui_status_bars.pyi b/labyrinth_engine/ui_status_bars.pyi new file mode 100644 index 0000000..b81af6f --- /dev/null +++ b/labyrinth_engine/ui_status_bars.pyi @@ -0,0 +1,22 @@ +from labyrinth_engine.lr_types import AnyPlayer + +from typing import Any, Dict, Union + +class Bar: + def __str__(self) -> str: ... + + def get(self, *args, **kwargs) -> Any: ... + + +class StringBar(Bar): + bar_type: str + name: str + values: Dict[AnyPlayer, Any] + + def __init__(self, name: str, init_values: Dict[AnyPlayer, Any]) -> None: ... + + def set_value(self, new_value: Any, player: AnyPlayer) -> None: ... + + def set_all_values(self, new_values: Dict[AnyPlayer, Any]) -> None: ... + + def get(self, player: AnyPlayer) -> Dict[str, Union[str, Any]]: ... diff --git a/labyrinth_objects/Vanilla/ammo.py b/labyrinth_objects/Vanilla/ammo.py index 5105698..51e7782 100644 --- a/labyrinth_objects/Vanilla/ammo.py +++ b/labyrinth_objects/Vanilla/ammo.py @@ -9,8 +9,8 @@ def __init__(self): super().__init__() - self.bullet_counter_bar = self.new_status_bar('Пули', None) - self.bomb_counter_bar = self.new_status_bar('Бомбы', None) + self.bullet_counter_bar = self.new_status_bar('Пули', {}) + self.bomb_counter_bar = self.new_status_bar('Бомбы', {}) def update_bars(self): self.bullet_counter_bar.set_all_values(self.bullets) @@ -20,8 +20,8 @@ def set_settings(self, settings, locations, items, creatures, players): self.MAX_BULLETS_COUNT = settings['max_bullets_count'] self.MAX_BOMBS_COUNT = settings['max_bombs_count'] - self.INIT_BULLETS_COUNT = settings.get('init_bullets_count') or self.MAX_BULLETS_COUNT - self.INIT_BOMBS_COUNT = settings.get('init_bombs_count') or self.MAX_BOMBS_COUNT + self.INIT_BULLETS_COUNT = settings.get('init_bullets_count', self.MAX_BULLETS_COUNT) + self.INIT_BOMBS_COUNT = settings.get('init_bombs_count', self.MAX_BOMBS_COUNT) self.bullets = {player: self.INIT_BULLETS_COUNT for player in players} self.bombs = {player: self.INIT_BOMBS_COUNT for player in players} diff --git a/labyrinth_objects/Vanilla/bomb.py b/labyrinth_objects/Vanilla/bomb.py index b1a1bf4..892736e 100644 --- a/labyrinth_objects/Vanilla/bomb.py +++ b/labyrinth_objects/Vanilla/bomb.py @@ -31,7 +31,7 @@ def blow_up(): current_location = active_player.get_parent() location_in_direction = current_location.get_neighbour(direction) - health = self.labyrinth.get_unique('health') + health = self.labyrinth.get_unique('health') # if type(location_in_direction) is Wall: location_in_direction.break_wall()