"""Der Koffer: Geometrie und Einlaufbewegung. Bewusst ohne ``pygame``-Abhängigkeit, damit die Regeln testbar bleiben. """ from __future__ import annotations from dataclasses import dataclass from . import config from .difficulty import DEFAULT_DIFFICULTY, Difficulty @dataclass class Case: """Ein Koffer im Auflieger. ``units_w`` / ``units_h`` beschreiben die **aktuelle** Grundfläche in Kasten-Einheiten. Eine Drehung tauscht die beiden Werte. ``texture`` merkt sich die Orientierung, in der der Koffer eingelaufen ist. Die Grafik bleibt dadurch immer dieselbe – ein gedrehter Koffer wird nur um 90° gedreht gezeichnet und bekommt keine andere Textur. """ units_w: int units_h: int x: float y: float color: tuple[int, int, int] = config.CASE_COLORS[0] texture: tuple[int, int] | None = None placed: bool = False snapped: bool = False allow_snap: bool = False can_rotate: bool = True def __post_init__(self) -> None: if self.texture is None: self.texture = (self.units_w, self.units_h) # -- Geometrie ------------------------------------------------------ @property def width(self) -> float: return self.units_w * config.UNIT_LENGTH @property def height(self) -> float: return self.units_h * config.UNIT_HEIGHT @property def right(self) -> float: return self.x + self.width @property def bottom(self) -> float: return self.y + self.height @property def is_rotated(self) -> bool: """Steht der Koffer quer zu seiner Textur?""" return (self.units_w, self.units_h) != self.texture # -- Bewegung ------------------------------------------------------- def move( self, dt: float, wall_x: float, difficulty: Difficulty = DEFAULT_DIFFICULTY, ) -> None: """Bewegt den Koffer nach links, mit Abbremsen kurz vor der Barriere.""" if self.placed: return distance = self.x - wall_x speed = ( difficulty.speed_fast if distance > config.FAST_TO_SLOW_DISTANCE else difficulty.speed_slow ) self.x -= speed * dt if self.x <= wall_x + config.SNAP_WINDOW: self.allow_snap = True def rotate_footprint(self) -> None: """Tauscht Breite und Höhe (nach einer 90°-Drehung).""" self.units_w, self.units_h = self.units_h, self.units_w def fits_trailer_height(self) -> bool: """Passt der Koffer nach einer Drehung noch in die Höhe des Aufliegers?""" return self.width <= config.TRAILER_HEIGHT