# Desktop Python teaching example. Numerical inputs are illustrative.
from collections import deque

def bfs(width, height, blocked, start, goal):
    valid = lambda p: 0 <= p[0] < width and 0 <= p[1] < height and p not in blocked
    if not valid(start) or not valid(goal):
        return None
    queue, parent = deque([start]), {start: None}
    while queue:
        point = queue.popleft()
        if point == goal:
            path = []
            while point is not None:
                path.append(point)
                point = parent[point]
            return path[::-1]
        x, y = point
        for nxt in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
            if valid(nxt) and nxt not in parent:
                parent[nxt] = point
                queue.append(nxt)
    return None

print(bfs(5, 5, {(2, 1), (2, 2), (2, 3)}, (0, 0), (4, 4)))
