from enum import Enum from typing import NamedTuple, Optional class Coords(NamedTuple): """ Вспомогательный класс для упрощения работы с координатами """ x: int | float y: int | float def __add__(self, other): if isinstance(other, self.__class__): return self.__class__(self.x + other.x, self.y + other.y) if isinstance(other, (int, float)): return self.__class__(self.x + other, self.y + other) return NotImplemented def __sub__(self, other): if isinstance(other, self.__class__): return self.__class__(self.x - other.x, self.y - other.y) if isinstance(other, (int, float)): return self.__class__(self.x - other, self.y - other) return NotImplemented def __floordiv__(self, other): if isinstance(other, self.__class__): return self.__class__(self.x // other.x, self.y // other.y) if isinstance(other, (int, float)): return self.__class__(self.x // other, self.y // other) return NotImplemented def __mul__(self, other): if isinstance(other, self.__class__): return self.__class__(self.x * other.x, self.y * other.y) if isinstance(other, (int, float)): return self.__class__(self.x * other, self.y * other) return NotImplemented def transform(self, ref: "Coords"): return self * ref def dir_norm(self): """нормализация вектора, но только для получения направления x, y могут быть только -1, 0, 1 может быть только направление по горизонтали либо по вертикали либо без направления """ src = self if self.x and self.y: src = ( self.__class__(self.x, 0) if abs(self.x) > abs(self.y) else self.__class__(0, self.y) ) return self.__class__(*((n > 0) - (n < 0) for n in src)) @classmethod def zero(cls): return cls(0, 0) class Direction(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 def as_coords(self): match self: case Direction.LEFT: return Coords(-1, 0) case Direction.RIGHT: return Coords(1, 0) case Direction.UP: return Coords(0, -1) case Direction.DOWN: return Coords(0, 1) @staticmethod def from_coords(coords: Coords) -> Optional["Direction"]: match coords.dir_norm(): case Coords(-1, 0): return Direction.LEFT case Coords(1, 0): return Direction.RIGHT case Coords(0, -1): return Direction.UP case Coords(0, 1): return Direction.DOWN