From 8221403ed0bc88fc921440d0e29817642651e20c Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Fri, 22 Oct 2021 18:46:28 +0200 Subject: [PATCH] grids \o/ --- grid.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 grid.py diff --git a/grid.py b/grid.py new file mode 100644 index 0000000..c2b8fe4 --- /dev/null +++ b/grid.py @@ -0,0 +1,105 @@ +from __future__ import annotations +from .coordinate import Coordinate +from typing import Union + +OFF_STATES = [False, 0, None] +OFF = False +ON = True + + +class Grid: + def __init__(self, default=False): + self.__default = default + self.__grid = {} + self.__minX = 0 + self.__minY = 0 + self.__maxX = 0 + self.__maxY = 0 + + 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 + + def toggle(self, pos: Coordinate): + if pos in self.__grid: + del self.__grid[pos] + else: + self.__trackBoundaries(pos) + self.__grid[pos] = not self.__default + + def set(self, pos: Coordinate, value: any): + if value in OFF_STATES and pos in self.__grid: + del self.__grid[pos] + elif value not in OFF_STATES: + self.__trackBoundaries(pos) + self.__grid[pos] = value + + def getState(self, pos: Coordinate) -> bool: + if pos not in self.__grid: + return False + 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 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), + ] + + def add(self, pos: Coordinate, value: Union[float, int] = 1): + if pos in self.__grid: + self.__grid[pos] += value + else: + self.__trackBoundaries(pos) + self.__grid[pos] = self.__default + value + + def sub(self, pos: Coordinate, value: Union[float, int] = 1): + if pos in self.__grid: + self.__grid[pos] -= value + else: + self.__trackBoundaries(pos) + self.__grid[pos] = self.__default - value + + def getSum(self, includeNegative: bool = True): + grid_sum = 0 + for value in self.__grid.values(): + if includeNegative or value > 0: + grid_sum += value + + return grid_sum + + def getNeighbourSum(self, pos: Coordinate, includeNegative: bool = True, includeDiagonal: bool = True) \ + -> Union[float, int]: + neighbour_sum = 0 + for neighbour in pos.getNeighbours( + includeDiagonal=includeDiagonal, + minX=self.__minX, minY=self.__minY, + maxX=self.__maxX, maxY=self.__maxY): + if neighbour in self.__grid: + if includeNegative or self.__grid[neighbour] > 0: + neighbour_sum += self.__grid[neighbour] + + return neighbour_sum