Grid.find(): generator yielding coordinates that hold a specific value

This commit is contained in:
Stefan Harmuth 2024-01-09 06:52:04 +01:00
parent cf72a5451f
commit d6fad1511c

View File

@ -173,6 +173,11 @@ class Grid:
def getOnCount(self) -> int:
return len(self.__grid)
def find(self, value: Any) -> Iterable[Coordinate]:
for k, v in self.__grid.items():
if v == value:
yield k
def count(self, value: Any) -> int:
return list(self.__grid.values()).count(value)
@ -210,14 +215,9 @@ class Grid:
and self.minZ + pad <= pos[2] <= self.maxZ - pad
)
else:
return (
self.minX + pad <= pos[0] <= self.maxX - pad
and self.minY + pad <= pos[1] <= self.maxY - pad
)
return self.minX + pad <= pos[0] <= self.maxX - pad and self.minY + pad <= pos[1] <= self.maxY - pad
def getActiveCells(
self, x: int = None, y: int = None, z: int = None
) -> Iterable[Coordinate]:
def getActiveCells(self, x: int = None, y: int = None, z: int = None) -> Iterable[Coordinate]:
if x is not None or y is not None or z is not None:
return (
c
@ -229,7 +229,7 @@ class Grid:
else:
return self.__grid.keys()
def getRegion(self, start: Coordinate, includeDiagonal: bool = False) -> Iterable[Coordinate]:
def getRegion(self, start: Coordinate, includeDiagonal: bool = False) -> Iterable[Coordinate]:
start_value = self.get(start)
queue = deque()
queue.append(start)
@ -421,9 +421,7 @@ class Grid:
if c in came_from and self.get(c) in walls:
continue
came_from[c] = current
if c == pos_to or (
stop_at_first is not None and self.get(c) == stop_at_first
):
if c == pos_to or (stop_at_first is not None and self.get(c) == stop_at_first):
pos_to = c
found_end = True
break
@ -470,9 +468,7 @@ class Grid:
if currentCoord == pos_to:
break
for neighbour in self.getNeighboursOf(
currentCoord, includeDefault=True, includeDiagonal=includeDiagonal
):
for neighbour in self.getNeighboursOf(currentCoord, includeDefault=True, includeDiagonal=includeDiagonal):
if self.get(neighbour) in walls or neighbour in closedNodes:
continue
@ -481,9 +477,7 @@ class Grid:
elif not includeDiagonal:
neighbourDist = 1
else:
neighbourDist = currentCoord.getDistanceTo(
neighbour, DistanceAlgorithm.MANHATTAN, includeDiagonal
)
neighbourDist = currentCoord.getDistanceTo(neighbour, DistanceAlgorithm.MANHATTAN, includeDiagonal)
targetDist = neighbour.getDistanceTo(pos_to)
f_cost = targetDist + neighbourDist + currentNode[1]
@ -517,17 +511,13 @@ class Grid:
to_z: int = None,
) -> "Grid":
if self.mode3D and (from_z is None or to_z is None):
raise ValueError(
"sub_grid() on mode3d Grids requires from_z and to_z to be set"
)
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 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(
@ -594,20 +584,14 @@ class Grid:
def get_aoc_ocr_string(self, x_shift: int = 0, y_shift: int = 0):
return convert_array_6(
[
[
"#" if self.get(Coordinate(x + x_shift, y + y_shift)) else "."
for x in self.rangeX()
]
["#" if self.get(Coordinate(x + x_shift, y + y_shift)) else "." for x in self.rangeX()]
for y in self.rangeY()
]
)
def __str__(self, true_char: str = "#", false_char: str = "."):
return "/".join(
"".join(
true_char if self.get(Coordinate(x, y)) else false_char
for x in range(self.minX, self.maxX + 1)
)
"".join(true_char if self.get(Coordinate(x, y)) else false_char for x in range(self.minX, self.maxX + 1))
for y in range(self.minY, self.maxY + 1)
)
@ -623,11 +607,7 @@ class Grid:
) -> "Grid":
if translate is None:
translate = {}
if (
true_char is not None
and True not in translate.values()
and true_char not in translate
):
if true_char is not None and True not in translate.values() and true_char not in translate:
translate[true_char] = true_value if true_value is not None else True
ret = cls(default=default)