68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
from collections import namedtuple
|
|
from typing import Union
|
|
|
|
# a position inside a grid.
|
|
Position = namedtuple("Position", ["y", "x", "value"])
|
|
|
|
|
|
class Grid:
|
|
"""
|
|
A class wrapping a 2-d array of Position instances with some convience methods.
|
|
"""
|
|
def __init__(self, data):
|
|
self.data = []
|
|
for y in range(len(data)):
|
|
row = []
|
|
for x in range(len(data[y])):
|
|
row.append(Position(y=y, x=x, value=data[y][x]))
|
|
self.data.append(row)
|
|
|
|
def at(self, y: int, x: int, default: Union[Position, None] = None) -> Union[Position, None]:
|
|
"""
|
|
Return the Position instance at the given grid coordinates. If the specified position does not exist,
|
|
return the specified default value, or None.
|
|
"""
|
|
try:
|
|
return self.data[y][x]
|
|
except IndexError:
|
|
return default
|
|
|
|
def north(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y - 1, position.x)
|
|
|
|
def east(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y, position.x + 1)
|
|
|
|
def south(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y + 1, position.x)
|
|
|
|
def west(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y, position.x - 1)
|
|
|
|
def northwest(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y - 1, position.x - 1)
|
|
|
|
def northeast(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y - 1, position.x + 1)
|
|
|
|
def southwest(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y + 1, position.x - 1)
|
|
|
|
def southeast(self, position: Position) -> Union[Position, None]:
|
|
return self.at(position.y + 1, position.x + 1)
|
|
|
|
def adjacent(self, position: Position) -> tuple:
|
|
"""
|
|
Return a tuple of all grid positions adjacent to the specified position, including diagonals.
|
|
"""
|
|
return (
|
|
self.northwest(position),
|
|
self.north(position),
|
|
self.northeast(position),
|
|
self.east(position),
|
|
self.southeast(position),
|
|
self.south(position),
|
|
self.southwest(position),
|
|
self.west(position),
|
|
)
|