diff --git a/grid.py b/grid.py index baa20c0..7ab23c8 100644 --- a/grid.py +++ b/grid.py @@ -9,7 +9,8 @@ ON = True class GridTransformation(Enum): - FLIP_HORIZONTALLY = 1 + FLIP_X = 1 + FLIP_HORIZONTALLY = 1 # alias for FLIP_X; prep for 3d-transformations FLIP_VERTICALLY = 2 FLIP_DIAGONALLY = 3 FLIP_DIAGONALLY_REV = 4 @@ -26,19 +27,18 @@ class Grid: self.minY = 0 self.maxX = 0 self.maxY = 0 + self.minZ = 0 + self.maxZ = 0 + self.mode3D = False def __trackBoundaries(self, pos: Coordinate): - if pos.x < self.minX: - self.minX = pos.x - - if pos.y < self.minY: - self.minY = pos.y - - if pos.x > self.maxX: - self.maxX = pos.x - - if pos.y > self.maxY: - self.maxY = pos.y + self.minX = min(self.minX, pos.x) + self.minY = min(self.minY, pos.y) + self.maxX = max(self.maxX, pos.x) + self.maxY = max(self.maxY, pos.y) + if self.mode3D: + self.minZ = min(self.minZ, pos.z) + self.maxZ = max(self.maxZ, pos.z) def toggle(self, pos: Coordinate): if pos in self.__grid: @@ -48,6 +48,9 @@ class Grid: self.__grid[pos] = not self.__default def set(self, pos: Coordinate, value: Any = True): + if pos.z is not None: + self.mode3D = True + if (value == self.__default or value in OFF_STATES) and pos in self.__grid: del self.__grid[pos] elif value != self.__default and value not in OFF_STATES: @@ -66,28 +69,41 @@ class Grid: else: return self.__grid[pos] not in OFF_STATES - def getValue(self, pos: Coordinate) -> any: - if pos not in self.__grid: - return self.__default - else: - return self.__grid[pos] - def getOnCount(self): return len(self.__grid) def isSet(self, pos: Coordinate) -> bool: return pos in self.__grid + def getCorners(self): + if not self.mode3D: + return [ + Coordinate(self.minX, self.minY), + Coordinate(self.minX, self.maxY), + Coordinate(self.maxX, self.minY), + Coordinate(self.maxX, self.maxY), + ] + else: + return [ + Coordinate(self.minX, self.minY, self.minZ), + Coordinate(self.minX, self.minY, self.maxZ), + Coordinate(self.minX, self.maxY, self.minZ), + Coordinate(self.minX, self.maxY, self.maxZ), + Coordinate(self.maxX, self.minY, self.minZ), + Coordinate(self.maxX, self.minY, self.maxZ), + Coordinate(self.maxX, self.maxY, self.minZ), + Coordinate(self.maxX, self.maxY, self.maxZ), + ] + def isCorner(self, pos: Coordinate) -> bool: - return pos in [ - Coordinate(self.minX, self.minY), - Coordinate(self.minX, self.maxY), - Coordinate(self.maxX, self.minY), - Coordinate(self.maxX, self.maxY), - ] + return pos in self.getCorners() def isWithinBoundaries(self, pos: Coordinate) -> bool: - return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= self.maxY + if self.mode3D: + return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= self.maxY \ + and self.minZ <= pos.z <= self.maxZ + else: + return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= self.maxY def add(self, pos: Coordinate, value: Union[float, int] = 1): self.set(pos, self.get(pos) + value) @@ -112,7 +128,8 @@ class Grid: for neighbour in pos.getNeighbours( includeDiagonal=includeDiagonal, minX=self.minX, minY=self.minY, - maxX=self.maxX, maxY=self.maxY): + maxX=self.maxX, maxY=self.maxY, + minZ=self.minZ, maxZ=self.maxZ): if neighbour in self.__grid: if includeNegative or self.__grid[neighbour] > 0: neighbour_sum += self.__grid[neighbour] @@ -125,6 +142,9 @@ class Grid: self.set(c2, buf) def transform(self, mode: GridTransformation): + if self.mode3D: + raise NotImplementedError() # that will take some time and thought + if mode == GridTransformation.FLIP_HORIZONTALLY: for x in range(self.minX, (self.maxX - self.minX) // 2 + 1): for y in range(self.minY, self.maxY + 1):