Grid: a whole bunch of bugfixing around transformations and mode3d

Grid: added __eq__()
This commit is contained in:
Stefan Harmuth 2022-12-25 18:36:37 +01:00
parent 69a63c94f6
commit 9f11e12bc4

View File

@ -186,12 +186,13 @@ class Grid:
return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= self.maxY return self.minX <= pos.x <= self.maxX and self.minY <= pos.y <= self.maxY
def getActiveCells(self, x: int = None, y: int = None, z: int = None) -> List[Coordinate]: def getActiveCells(self, x: int = None, y: int = None, z: int = None) -> List[Coordinate]:
if x: if x is not None or y is not None or z is not None:
return [c for c in self.__grid.keys() if c.x == x] return [
elif y: c for c in self.__grid.keys()
return [c for c in self.__grid.keys() if c.y == y] if (c.x == x if x is not None else True)
elif z: and (c.y == y if y is not None else True)
return [c for c in self.__grid.keys() if c.z == z] and (c.z == z if z is not None else True)
]
else: else:
return list(self.__grid.keys()) return list(self.__grid.keys())
@ -259,41 +260,55 @@ class Grid:
coords = self.__grid coords = self.__grid
self.__grid = {} self.__grid = {}
if mode == GridTransformation.ROTATE_X: if mode == GridTransformation.ROTATE_X:
self.minY, self.maxY, self.minZ, self.maxZ = self.minZ, self.maxZ, -self.maxY, -self.minY shift_z = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.x, -c.z, c.y), v)
elif mode == GridTransformation.ROTATE_Y:
self.minX, self.maxX, self.minZ, self.maxZ = -self.maxZ, -self.minZ, self.minX, self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.z, c.y, c.x), v)
elif mode == GridTransformation.ROTATE_Z:
self.minX, self.maxX, self.minY, self.maxY = -self.maxY, -self.minY, self.minX, self.minY
for c, v in coords.items():
self.set(Coordinate(-c.y, c.x, c.z), v)
elif mode == GridTransformation.COUNTER_ROTATE_X:
self.minY, self.maxY, self.minZ, self.maxZ = -self.maxZ, -self.minZ, self.minY, self.maxY
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(c.x, c.z, -c.y), v) self.set(Coordinate(c.x, c.z, -c.y), v)
self.shift(shift_z=shift_z)
elif mode == GridTransformation.ROTATE_Y:
shift_x = self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.z, c.y, c.x), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.ROTATE_Z:
shift_x = self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.y, c.x, c.z), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.COUNTER_ROTATE_X:
shift_y = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.x, -c.z, c.y), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.COUNTER_ROTATE_Y: elif mode == GridTransformation.COUNTER_ROTATE_Y:
self.minX, self.maxX, self.minZ, self.maxZ = self.minZ, self.maxZ, -self.minX, -self.maxX shift_z = self.maxZ
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(c.z, c.y, -c.x), v) self.set(Coordinate(c.z, c.y, -c.x), v)
self.shift(shift_z=shift_z)
elif mode == GridTransformation.COUNTER_ROTATE_Z: elif mode == GridTransformation.COUNTER_ROTATE_Z:
self.minX, self.maxX, self.minY, self.maxY = self.minY, self.maxY, -self.minX, -self.maxX shift_y = self.maxY
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(c.y, -c.x, c.z), v) self.set(Coordinate(c.y, -c.x, c.z), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.FLIP_X: elif mode == GridTransformation.FLIP_X:
shift_x = self.maxX
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(-c.x, c.y, c.z), v) self.set(Coordinate(-c.x, c.y, c.z), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.FLIP_Y: elif mode == GridTransformation.FLIP_Y:
shift_y = self.maxY
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(c.x, -c.y, c.z), v) self.set(Coordinate(c.x, -c.y, c.z), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.FLIP_Z: elif mode == GridTransformation.FLIP_Z:
shift_z = self.maxZ
for c, v in coords.items(): for c, v in coords.items():
self.set(Coordinate(c.x, c.y, -c.z), v) self.set(Coordinate(c.x, c.y, -c.z), v)
self.shift(shift_z=shift_z)
else: else:
raise NotImplementedError(mode) raise NotImplementedError(mode)
self.recalcBoundaries()
def shift(self, shift_x: int = 0, shift_y: int = 0, shift_z: int = 0): def shift(self, shift_x: int = 0, shift_y: int = 0, shift_z: int = 0):
self.minX, self.minY = self.minX + shift_x, self.minY + shift_y self.minX, self.minY = self.minX + shift_x, self.minY + shift_y
self.maxX, self.maxY = self.maxX + shift_x, self.maxY + shift_y self.maxX, self.maxY = self.maxX + shift_x, self.maxY + shift_y
@ -403,12 +418,21 @@ class Grid:
return pathCoords return pathCoords
def sub_grid(self, from_x: int, from_y: int, to_x: int, to_y: int) -> 'Grid': def sub_grid(self, from_x: int, from_y: int, to_x: int, to_y: int, from_z: int = None, to_z: int = None) -> 'Grid':
count_x, count_y = 0, 0 if self.mode3D and (from_z is None or to_z is None):
new_grid = Grid() raise ValueError("sub_grid() on mode3d Grids requires from_z and to_z to be set")
count_x, count_y, count_z = 0, 0, 0
new_grid = Grid(self.__default)
for x in range(from_x, to_x + 1): for x in range(from_x, to_x + 1):
for y in range(from_y, to_y + 1): for y in range(from_y, to_y + 1):
if not self.mode3D:
new_grid.set(Coordinate(count_x, count_y), self.get(Coordinate(x, y))) new_grid.set(Coordinate(count_x, count_y), self.get(Coordinate(x, y)))
else:
for z in range(from_z, to_z + 1):
new_grid.set(Coordinate(count_x, count_y, count_z), self.get(Coordinate(x, y, z)))
count_z += 1
count_z = 0
count_y += 1 count_y += 1
count_y = 0 count_y = 0
count_x += 1 count_x += 1
@ -424,7 +448,7 @@ class Grid:
put_y = y put_y = y
put_x += 1 put_x += 1
def print(self, spacer: str = "", true_char: str = '#', false_char: str = " ", translate: dict = None, mark: list = None): def print(self, spacer: str = "", true_char: str = '#', false_char: str = " ", translate: dict = None, mark: list = None, z_level: int = None):
if translate is None: if translate is None:
translate = {} translate = {}
@ -435,7 +459,8 @@ class Grid:
for y in range(self.minY, self.maxY + 1): for y in range(self.minY, self.maxY + 1):
for x in range(self.minX, self.maxX + 1): for x in range(self.minX, self.maxX + 1):
pos = Coordinate(x, y) pos = Coordinate(x, y, z_level)
if mark and pos in mark: if mark and pos in mark:
print("X", end="") print("X", end="")
else: else:
@ -486,3 +511,18 @@ class Grid:
ret.set(coord, c) ret.set(coord, c)
return ret return ret
def __eq__(self, other: Grid) -> bool:
if not isinstance(other, Grid):
return False
other_active = set(other.getActiveCells())
for c, v in self.__grid.items():
if other.get(c) != v:
return False
other_active.remove(c)
if other_active:
return False
return True