Skip to content

latent_sokoban.solver

latent_sokoban.solver

Breadth-first Sokoban solver and deadlock detection.

Competition note: per the rules, the symbolic solver may be used for training-data generation and evaluation analysis ONLY. Agents may not call it at inference time.

bfs_solve

bfs_solve(level, max_nodes=200000)

Return an optimal (shortest) action sequence, or None if unsolvable or the node budget is exhausted.

Source code in latent_sokoban/solver.py
def bfs_solve(level: Level, max_nodes: int = 200_000) -> list[int] | None:
    """Return an optimal (shortest) action sequence, or None if unsolvable
    or the node budget is exhausted."""
    start = (level.player, level.boxes)
    goal_boxes = level.goals
    if level.boxes == goal_boxes:
        return []
    frontier = deque([start])
    parents: dict[tuple, tuple[tuple, int] | None] = {start: None}
    nodes = 0
    while frontier:
        key = frontier.popleft()
        nodes += 1
        if nodes > max_nodes:
            return None
        for action in ACTIONS:
            nxt = SokobanEnv.apply(level, key, action)
            if nxt == key or nxt in parents:
                continue
            parents[nxt] = (key, action)
            if nxt[1] == goal_boxes:
                actions = []
                cur = nxt
                while parents[cur] is not None:
                    cur, a = parents[cur]
                    actions.append(a)
                return actions[::-1]
            # prune states with a corner-deadlocked box off-goal
            if not _has_corner_deadlock(level, nxt[1]):
                frontier.append(nxt)
    return None

is_deadlocked

is_deadlocked(level, boxes)

Cheap sufficient deadlock test: a box off-goal stuck in a corner.

Used by the evaluation harness to report deadlock rate; never available to agents. For an exact test use state_is_dead.

Source code in latent_sokoban/solver.py
def is_deadlocked(level: Level, boxes: frozenset) -> bool:
    """Cheap sufficient deadlock test: a box off-goal stuck in a corner.

    Used by the evaluation harness to report deadlock rate; never
    available to agents. For an exact test use state_is_dead."""
    if boxes == level.goals:
        return False
    return _has_corner_deadlock(level, boxes)

state_is_dead

state_is_dead(level, key, max_nodes=50000)

Exact (bounded) deadlock test for a full state key (player, boxes).

Source code in latent_sokoban/solver.py
def state_is_dead(level: Level, key: tuple, max_nodes: int = 50_000) -> bool:
    """Exact (bounded) deadlock test for a full state key (player, boxes)."""
    player, boxes = key
    if boxes == level.goals:
        return False
    probe = Level(level.walls, level.goals, frozenset(boxes), player)
    return bfs_solve(probe, max_nodes) is None