From 8b9897f0ccdd02739f996a3d854a8334f69bafb3 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 1 May 2022 17:32:48 -0700 Subject: [PATCH] Convert the geometry types to frozen dataclasses --- roguebasin/geometry.py | 68 +++++++++++------------------------------- roguebasin/map.py | 2 +- 2 files changed, 18 insertions(+), 52 deletions(-) diff --git a/roguebasin/geometry.py b/roguebasin/geometry.py index 12d0383..7c190dc 100644 --- a/roguebasin/geometry.py +++ b/roguebasin/geometry.py @@ -1,78 +1,46 @@ #!/usr/bin/env python3 # Eryn Wells -from typing import Tuple, overload +from dataclasses import dataclass +from typing import Any, Tuple, overload +@dataclass(frozen=True) class Point: - __slots__ = ('x', 'y') - - def __init__(self, x: int = 0, y: int = 0): - self.x = x - self.y = y + x: int = 0 + y: int = 0 @overload def __add__(self, other: 'Vector') -> 'Point': ... - def __add__(self, other) -> 'Point': + def __add__(self, other: Any) -> 'Point': if not isinstance(other, Vector): raise TypeError('Only Vector can be added to a Point') return Point(self.x + other.dx, self.y + other.dy) - @overload - def __eq__(self, other: 'Point') -> bool: - ... - - def __eq__(self, other): - if not isinstance(other, Point): - raise TypeError('Points can only be compared to other Points') - return self.x == other.x and self.y == other.y - def __str__(self): return f'(x:{self.x}, y:{self.y})' - def __repr__(self): - return f'Point({self.x}, {self.y})' - +@dataclass(frozen=True) class Vector: - __slots__ = ('dx', 'dy') - - def __init__(self, dx: int = 0, dy: int = 0): - self.dx = dx - self.dy = dy + dx: int = 0 + dy: int = 0 def __str__(self): return f'(δx:{self.x}, δy:{self.y})' - def __repr__(self): - return f'Vector({self.x}, {self.y})' - +@dataclass(frozen=True) class Size: - __slots__ = ('width', 'height') - - def __init__(self, width: int = 0, height: int = 0): - self.width = width - self.height = height - - @property - def as_tuple(self) -> Tuple[int, int]: - return (self.width, self.height) + width: int = 0 + height: int = 0 def __str__(self): return f'(w:{self.width}, h:{self.height})' - def __repr__(self): - return f'Size({self.width}, {self.height})' - +@dataclass(frozen=True) class Rect: - __slots__ = ('origin', 'size') - - def __init__(self, x: int = 0, y: int = 0, w: int = 0, h: int = 0): - ''' - Construct a new rectangle. - ''' - self.origin = Point(x, y) - self.size = Size(w, h) + origin: Point + size: Size @property def min_x(self) -> int: @@ -108,8 +76,6 @@ class Rect: def midpoint(self) -> Point: return Point(self.mid_x, self.mid_y) - def __str__(self): - return f'[{self.origin}, {self.size}]' - def __repr__(self): - return f'{self.__class__.__name__}({self.origin.x}, {self.origin.y}, {self.size.width}, {self.size.height})' \ No newline at end of file + def __str__(self): + return f'[{self.origin}, {self.size}]' \ No newline at end of file diff --git a/roguebasin/map.py b/roguebasin/map.py index db106a7..5a2bc73 100644 --- a/roguebasin/map.py +++ b/roguebasin/map.py @@ -90,7 +90,7 @@ class RoomsAndCorridorsGenerator(MapGenerator): self.rng.randint(5, min(15, max(5, node.height - 2)))) origin = Point(node.x + self.rng.randint(1, max(1, node.width - size.width - 1)), node.y + self.rng.randint(1, max(1, node.height - size.height - 1))) - bounds = Rect(origin.x, origin.y, size.width, size.height) + bounds = Rect(origin, size) LOG.debug(f'{" " * indent}`-> {bounds}')