diff --git a/main.py b/main.py index 2160183..118668b 100755 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ #!/usr/bin/env python import argparse +import sys from loguru import logger from utils import BASE_PATH, CONFIG, GameMode @@ -27,28 +28,46 @@ parser.add_argument( help="Run app with GUI [Default]", ) -logger.add( - BASE_PATH / ".logs" / "teris.log", - format="{time} | {level} | {message}", - level="WARNING", - rotation="10 MB", - compression="zip", -) + +def setup_logger(level: str = "warning") -> None: + logger.remove() + logger.add( + sink=sys.stdout, + format="{time} | {level} | {message}", + level=level.upper(), + colorize=True, + ) + + logger.add( + BASE_PATH / ".logs" / "teris.log", + format="{time} | {level} | {message}", + level="DEBUG" if level.upper() == "DEBUG" else "INFO", + rotation="10 MB", + compression="zip", + ) @logger.catch -def main(args: argparse.ArgumentParser) -> None: - if args.debug: - CONFIG.log_level = "debug" - elif args.verbose: - CONFIG.log_level = "info" - +def run() -> None: import game - game.log.debug("Running the game") + logger.debug("Launching the game") game.Main(GameMode.PLAYER).run() +def main(args: argparse.ArgumentParser) -> None: + if args.debug: + level = "debug" + elif args.verbose: + level = "info" + else: + level = "warning" + + setup_logger(level) + + run() + + if __name__ == "__main__": args = parser.parse_args() main(args) diff --git a/src/game/__init__.py b/src/game/__init__.py index de7f5b2..dc4eb62 100644 --- a/src/game/__init__.py +++ b/src/game/__init__.py @@ -1,4 +1,3 @@ -from .log import log from .screens import Game, Main, Preview, Score, Tetris -__all__ = ["Main", "Game", "Preview", "Score", "Tetris", "log"] +__all__ = ["Main", "Game", "Preview", "Score", "Tetris"] diff --git a/src/game/log.py b/src/game/log.py deleted file mode 100644 index a793b36..0000000 --- a/src/game/log.py +++ /dev/null @@ -1,14 +0,0 @@ -from loguru import logger -from utils import BASE_PATH, CONFIG - -log = logger.bind(name="game") - - -log.add( - BASE_PATH / ".logs" / "game.log", - format="{time} | {level} | {message}", - level=CONFIG.log_level.upper(), - rotation="10 MB", - compression="zip", - filter=lambda record: record["extra"].get("name") == "game", -) diff --git a/src/game/screens/game.py b/src/game/screens/game.py index 9a9667c..19d127a 100644 --- a/src/game/screens/game.py +++ b/src/game/screens/game.py @@ -1,9 +1,9 @@ from typing import Any import pygame +from loguru import logger from utils import CONFIG, Figure, GameMode -from game.log import log from game.sprites import Tetromino from .base import BaseScreen diff --git a/src/game/screens/main.py b/src/game/screens/main.py index 726683b..95cc4a4 100644 --- a/src/game/screens/main.py +++ b/src/game/screens/main.py @@ -2,19 +2,17 @@ import sys from typing import Optional import pygame +from loguru import logger from utils import CONFIG, GameMode, read_settings -from game.log import log - from .base import BaseScreen, SceenElement, TextScreen from .button import Button from .game import Game -from .settings import Settings class Main(BaseScreen, SceenElement, TextScreen): def __init__(self, mode: GameMode) -> None: - log.info("Initializing the game") + logger.info("Initializing the game") self._initialize_pygame() self._initialize_surface() self._initialize_rect() @@ -24,7 +22,6 @@ class Main(BaseScreen, SceenElement, TextScreen): self.settings = read_settings() self.game: Optional[Game] = None self.game_mode = mode - self.settings_screen: Optional[Settings] = None def draw(self) -> None: """Update the display.""" @@ -66,7 +63,7 @@ class Main(BaseScreen, SceenElement, TextScreen): def exit(self) -> None: """Exit the game.""" - log.info("Exiting the game") + logger.info("Exiting the game") pygame.quit() sys.exit() @@ -75,16 +72,11 @@ class Main(BaseScreen, SceenElement, TextScreen): self.game = Game(self.game_mode, self.settings) return self - def open_settings(self) -> "Main": - self._draw_background() - self.settings_screen = Settings() - return self - def _set_buttons(self) -> None: self.buttons: list[Button] = [ Button("Play", self.play), Button("AI", None), - Button("Settings", self.open_settings), + Button("Settings", None), Button("Quit", self.exit), ] diff --git a/src/game/screens/preview.py b/src/game/screens/preview.py index e0b98a7..15e34e3 100644 --- a/src/game/screens/preview.py +++ b/src/game/screens/preview.py @@ -1,4 +1,5 @@ import pygame +from loguru import logger from utils import CONFIG, Figure, Size from .base import BaseScreen, SceenElement diff --git a/src/game/screens/score.py b/src/game/screens/score.py index 227e885..9d39c1f 100644 --- a/src/game/screens/score.py +++ b/src/game/screens/score.py @@ -1,8 +1,7 @@ import pygame +from loguru import logger from utils import CONFIG, GameMode, Size -from game.log import log - from .base import BaseScreen, SceenElement, TextScreen diff --git a/src/game/screens/settings.py b/src/game/screens/settings.py deleted file mode 100644 index 189f2e4..0000000 --- a/src/game/screens/settings.py +++ /dev/null @@ -1,99 +0,0 @@ -import pygame -from utils import CONFIG, Size - -from game.log import log - -from .base import BaseScreen, SceenElement, TextScreen -from .button import Button - - -class Settings(BaseScreen, SceenElement, TextScreen): - def __init__(self) -> None: - self._initialize_surface() - self._initialize_rect() - self._initialize_font() - self._set_buttons() - self._initialize_increment_height() - - def draw(self) -> None: - """Update the display.""" - self._draw_background() - self._draw_text() - - def run(self) -> None: - self.draw() - - def update(self) -> None: - pass - - def _draw_text(self) -> None: - """Draw the text on the score surface.""" - for idx, text in enumerate(self.text): - x = self.surface.get_width() / 2 - y = self.increment_height / 2 + idx * self.increment_height - self._display_text(text, pygame.Vector2(x, y)) - - def _display_text(self, text_value: tuple[str, int], pos: pygame.Vector2) -> None: - """ - Display a single text element on the score surface. - - Args: - text_value: A tuple containing the label and value of the text element. - pos: The position (x, y) where the text should be displayed. - """ - - text, value = text_value - - if len(text) >= 10: - text_surface = self.font.render(f"{text}:", True, CONFIG.colors.fg_sidebar) - - value_surface = self.font.render(f"{value}", True, CONFIG.colors.fg_sidebar) - value_rect = value_surface.get_rect(center=(pos.x, pos.y + 40)) - - self.surface.blit(value_surface, value_rect) - else: - text_surface = self.font.render( - f"{text}:{value}", True, CONFIG.colors.fg_sidebar - ) - text_rect = text_surface.get_rect(center=pos) - self.surface.blit(text_surface, text_rect) - - text_rect = text_surface.get_rect(center=pos) - self.surface.blit(text_surface, text_rect) - - def _draw_border(self) -> None: - """Draw the border of the score surface.""" - pygame.draw.rect( - self.display_surface, - CONFIG.colors.border_highlight, - self.rect, - CONFIG.game.line_width * 2, - CONFIG.game.border_radius, - ) - - def _draw_background(self) -> None: - """Fill the background of the score display.""" - self.surface.fill(CONFIG.colors.bg_sidebar) - - def _initialize_surface(self) -> None: - """Initialize the score surface.""" - self.surface = pygame.Surface(CONFIG.sidebar.score) - self.display_surface = pygame.display.get_surface() - - def _initialize_rect(self) -> None: - """Initialize the score rectangle.""" - self.rect = self.surface.get_rect( - bottomright=CONFIG.window.size - CONFIG.window.padding - ) - - def _initialize_font(self) -> None: - """Initialize the font used to display the score.""" - self.font = pygame.font.Font(CONFIG.font.family, CONFIG.font.size) - - def _initialize_increment_height(self) -> None: - """Initialize the increment height for positioning text elements.""" - self.increment_height = self.surface.get_height() / len(self.text) - - def _update_display_surface(self) -> None: - """Update the display surface.""" - self.display_surface.blit(self.surface, self.rect) diff --git a/src/game/screens/tetris.py b/src/game/screens/tetris.py index 99da10e..e4da33a 100644 --- a/src/game/screens/tetris.py +++ b/src/game/screens/tetris.py @@ -2,9 +2,9 @@ from typing import Any, Callable, Optional import numpy as np import pygame +from loguru import logger from utils import CONFIG, Direction, Figure, GameMode, Rotation -from game.log import log from game.sprites import Block, Tetromino from game.timer import Timer, Timers @@ -195,13 +195,13 @@ class Tetris(BaseScreen): """ for block in self.tetromino.blocks: if block.pos.y <= 0: - log.info("Game over!") + logger.info("Game over!") return True return False def restart(self) -> None: """Restart the game.""" - log.info("Restarting the game") + logger.info("Restarting the game") self._reset_game_state() self._initialize_field_and_tetromino() self.game_over = False diff --git a/src/game/sprites/block.py b/src/game/sprites/block.py index 57285a9..13b245d 100644 --- a/src/game/sprites/block.py +++ b/src/game/sprites/block.py @@ -2,10 +2,9 @@ from typing import Any, Optional import numpy as np import pygame +from loguru import logger from utils import CONFIG, Rotation, Size -from game.log import log - class Block(pygame.sprite.Sprite): """ diff --git a/src/game/sprites/tetromino.py b/src/game/sprites/tetromino.py index 559a0a9..13bc961 100644 --- a/src/game/sprites/tetromino.py +++ b/src/game/sprites/tetromino.py @@ -2,10 +2,9 @@ from typing import Any, Callable, Optional import numpy as np import pygame +from loguru import logger from utils import CONFIG, Direction, Figure, Rotation, Size -from game.log import log - from .block import Block diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 2d4dc42..1c42e46 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,7 +1,6 @@ from .config import CONFIG from .enum import Direction, GameMode, Rotation from .figure import Figure, FigureConfig -from .log import log from .path import BASE_PATH from .settings import read_settings, save_settings from .tuples import Size @@ -9,7 +8,6 @@ from .tuples import Size __all__ = [ "BASE_PATH", "CONFIG", - "log", "Size", "Figure", "FigureConfig", diff --git a/src/utils/colors/tokyonight/base.py b/src/utils/colors/tokyonight/base.py new file mode 100644 index 0000000..6b27579 --- /dev/null +++ b/src/utils/colors/tokyonight/base.py @@ -0,0 +1,63 @@ +from abc import ABC, ABCMeta + +from attrs import define + + +class Color(ABC, metaclass=ABCMeta): + bg: str + bg_dark: str + bg_float: str + bg_highlight: str + bg_popup: str + bg_search: str + bg_sidebar: str + bg_statusline: str + bg_visual: str + black: str + blue: str + blue0: str + blue1: str + blue2: str + blue5: str + blue6: str + blue7: str + border: str + border_highlight: str + comment: str + cyan: str + dark3: str + dark5: str + delta_add: str + delta_delete: str + diff_add: str + diff_change: str + diff_delete: str + diff_text: str + error: str + fg: str + fg_dark: str + fg_float: str + fg_gutter: str + fg_sidebar: str + git_add: str + git_change: str + git_delete: str + git_ignore: str + git_signs_add: str + git_signs_change: str + git_signs_delete: str + green: str + green1: str + green2: str + hint: str + info: str + magenta: str + magenta2: str + orange: str + purple: str + red: str + red1: str + teal: str + terminal_black: str + warning: str + yellow: str diff --git a/src/utils/colors/tokyonight/day.py b/src/utils/colors/tokyonight/day.py index 2a89909..216778f 100644 --- a/src/utils/colors/tokyonight/day.py +++ b/src/utils/colors/tokyonight/day.py @@ -1,8 +1,10 @@ from attr import define +from .base import Color + @define -class TokyoNightDay: +class TokyoNightDay(Color): bg = "#e1e2e7" bg_dark = "#e9e9ec" bg_float = "#e9e9ec" diff --git a/src/utils/colors/tokyonight/moon.py b/src/utils/colors/tokyonight/moon.py index e9b6e64..4e191a0 100644 --- a/src/utils/colors/tokyonight/moon.py +++ b/src/utils/colors/tokyonight/moon.py @@ -1,8 +1,10 @@ from attr import define +from .base import Color + @define -class TokyoNightMoon: +class TokyoNightMoon(Color): bg = "#222436" bg_dark = "#1e2030" bg_float = "#1e2030" diff --git a/src/utils/colors/tokyonight/night.py b/src/utils/colors/tokyonight/night.py index 6cdcdbf..d808982 100644 --- a/src/utils/colors/tokyonight/night.py +++ b/src/utils/colors/tokyonight/night.py @@ -1,8 +1,10 @@ from attr import define +from .base import Color + @define -class TokyoNightNight: +class TokyoNightNight(Color): bg = "#1a1b26" bg_dark = "#16161e" bg_float = "#16161e" diff --git a/src/utils/colors/tokyonight/storm.py b/src/utils/colors/tokyonight/storm.py index b8d490f..6d15e20 100644 --- a/src/utils/colors/tokyonight/storm.py +++ b/src/utils/colors/tokyonight/storm.py @@ -1,8 +1,10 @@ from attr import define +from .base import Color + @define -class TokyoNightStorm: +class TokyoNightStorm(Color): bg = "#24283b" bg_dark = "#1f2335" bg_float = "#1f2335" diff --git a/src/utils/config.py b/src/utils/config.py index 3514e60..c25e248 100644 --- a/src/utils/config.py +++ b/src/utils/config.py @@ -3,7 +3,8 @@ from pathlib import Path from attr import define from pygame import Vector2 as Vec2 -from .colors import COLOR_DICT +from .colors import COLOR_DICT, TokyoNightNight +from .colors.tokyonight.base import Color from .path import BASE_PATH from .settings import read_settings from .tuples import Size @@ -85,14 +86,14 @@ class AI: @define class Config: - log_level: str = "warning" - game: Game = Game() sidebar: SideBar = SideBar() window: Window = Window() font: Font = Font() music: Music = Music() - colors = COLOR_DICT[read_settings()["General"]["colorscheme"]]() + colors: Color = COLOR_DICT.get( + read_settings()["General"]["colorscheme"], TokyoNightNight + )() ai = AI() fps: int = 60 diff --git a/src/utils/log.py b/src/utils/log.py deleted file mode 100644 index 84264ac..0000000 --- a/src/utils/log.py +++ /dev/null @@ -1,15 +0,0 @@ -from loguru import logger - -from .config import CONFIG -from .path import BASE_PATH - -log = logger.bind(name="utils") - -log.add( - BASE_PATH / ".logs" / "utils.log", - format="{time} | {level} | {message}", - level=CONFIG.log_level.upper(), - rotation="10 MB", - compression="zip", - filter=lambda record: record["extra"].get("name") == "utils", -) diff --git a/src/utils/settings.py b/src/utils/settings.py index c5c616f..1514308 100644 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -2,6 +2,7 @@ from pathlib import Path from typing import Any, Optional import toml +from loguru import logger from .path import BASE_PATH @@ -25,10 +26,10 @@ def read_settings( """ try: with open(file_path, "r") as file: - return toml.load(file) + return dict(toml.load(file)) except FileNotFoundError: - log.error(f"Error: The file '{file_path}' does not exist.") + logger.error(f"Error: The file '{file_path}' does not exist.") return {} except toml.TomlDecodeError as e: - log.error(f"rror decoding TOML file: {e}") + logger.error(f"rror decoding TOML file: {e}") return {}