tilemapper/src/tilemapper/grid.py
2025-08-08 22:33:51 -07:00

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),
)