Grid(): expose boundaries Grid.isWithinBoundaries(): check if Coordinate is within boundaries Grid.getActiveCells(): get all Coordinates within Grid() with a value
112 lines
3.3 KiB
Python
112 lines
3.3 KiB
Python
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 isWithinBoundaries(self, pos: Coordinate) -> bool:
|
|
return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= 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 getActiveCells(self):
|
|
return [i for i in self.__grid.keys()]
|
|
|
|
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
|