grid.Grid: introduce rudimentary 3d support
This commit is contained in:
parent
75c7df6f19
commit
37166532ae
72
grid.py
72
grid.py
@ -9,7 +9,8 @@ ON = True
|
|||||||
|
|
||||||
|
|
||||||
class GridTransformation(Enum):
|
class GridTransformation(Enum):
|
||||||
FLIP_HORIZONTALLY = 1
|
FLIP_X = 1
|
||||||
|
FLIP_HORIZONTALLY = 1 # alias for FLIP_X; prep for 3d-transformations
|
||||||
FLIP_VERTICALLY = 2
|
FLIP_VERTICALLY = 2
|
||||||
FLIP_DIAGONALLY = 3
|
FLIP_DIAGONALLY = 3
|
||||||
FLIP_DIAGONALLY_REV = 4
|
FLIP_DIAGONALLY_REV = 4
|
||||||
@ -26,19 +27,18 @@ class Grid:
|
|||||||
self.minY = 0
|
self.minY = 0
|
||||||
self.maxX = 0
|
self.maxX = 0
|
||||||
self.maxY = 0
|
self.maxY = 0
|
||||||
|
self.minZ = 0
|
||||||
|
self.maxZ = 0
|
||||||
|
self.mode3D = False
|
||||||
|
|
||||||
def __trackBoundaries(self, pos: Coordinate):
|
def __trackBoundaries(self, pos: Coordinate):
|
||||||
if pos.x < self.minX:
|
self.minX = min(self.minX, pos.x)
|
||||||
self.minX = pos.x
|
self.minY = min(self.minY, pos.y)
|
||||||
|
self.maxX = max(self.maxX, pos.x)
|
||||||
if pos.y < self.minY:
|
self.maxY = max(self.maxY, pos.y)
|
||||||
self.minY = pos.y
|
if self.mode3D:
|
||||||
|
self.minZ = min(self.minZ, pos.z)
|
||||||
if pos.x > self.maxX:
|
self.maxZ = max(self.maxZ, pos.z)
|
||||||
self.maxX = pos.x
|
|
||||||
|
|
||||||
if pos.y > self.maxY:
|
|
||||||
self.maxY = pos.y
|
|
||||||
|
|
||||||
def toggle(self, pos: Coordinate):
|
def toggle(self, pos: Coordinate):
|
||||||
if pos in self.__grid:
|
if pos in self.__grid:
|
||||||
@ -48,6 +48,9 @@ class Grid:
|
|||||||
self.__grid[pos] = not self.__default
|
self.__grid[pos] = not self.__default
|
||||||
|
|
||||||
def set(self, pos: Coordinate, value: Any = True):
|
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:
|
if (value == self.__default or value in OFF_STATES) and pos in self.__grid:
|
||||||
del self.__grid[pos]
|
del self.__grid[pos]
|
||||||
elif value != self.__default and value not in OFF_STATES:
|
elif value != self.__default and value not in OFF_STATES:
|
||||||
@ -66,28 +69,41 @@ class Grid:
|
|||||||
else:
|
else:
|
||||||
return self.__grid[pos] not in OFF_STATES
|
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):
|
def getOnCount(self):
|
||||||
return len(self.__grid)
|
return len(self.__grid)
|
||||||
|
|
||||||
def isSet(self, pos: Coordinate) -> bool:
|
def isSet(self, pos: Coordinate) -> bool:
|
||||||
return pos in self.__grid
|
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:
|
def isCorner(self, pos: Coordinate) -> bool:
|
||||||
return pos in [
|
return pos in self.getCorners()
|
||||||
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:
|
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):
|
def add(self, pos: Coordinate, value: Union[float, int] = 1):
|
||||||
self.set(pos, self.get(pos) + value)
|
self.set(pos, self.get(pos) + value)
|
||||||
@ -112,7 +128,8 @@ class Grid:
|
|||||||
for neighbour in pos.getNeighbours(
|
for neighbour in pos.getNeighbours(
|
||||||
includeDiagonal=includeDiagonal,
|
includeDiagonal=includeDiagonal,
|
||||||
minX=self.minX, minY=self.minY,
|
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 neighbour in self.__grid:
|
||||||
if includeNegative or self.__grid[neighbour] > 0:
|
if includeNegative or self.__grid[neighbour] > 0:
|
||||||
neighbour_sum += self.__grid[neighbour]
|
neighbour_sum += self.__grid[neighbour]
|
||||||
@ -125,6 +142,9 @@ class Grid:
|
|||||||
self.set(c2, buf)
|
self.set(c2, buf)
|
||||||
|
|
||||||
def transform(self, mode: GridTransformation):
|
def transform(self, mode: GridTransformation):
|
||||||
|
if self.mode3D:
|
||||||
|
raise NotImplementedError() # that will take some time and thought
|
||||||
|
|
||||||
if mode == GridTransformation.FLIP_HORIZONTALLY:
|
if mode == GridTransformation.FLIP_HORIZONTALLY:
|
||||||
for x in range(self.minX, (self.maxX - self.minX) // 2 + 1):
|
for x in range(self.minX, (self.maxX - self.minX) // 2 + 1):
|
||||||
for y in range(self.minY, self.maxY + 1):
|
for y in range(self.minY, self.maxY + 1):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user