Skip to main content

pathviz

Generate mazes, run pathfinding algorithms on them, and watch the search happen.

Maze generation, search and drawing are three independent modules. The only thing they share is a plain adjacency list, dict[(x, y), set[(x, y)]], so you can use any one of them without the other two, and drop your own algorithm in anywhere.

Install

pip install pathviz

pygame comes with it, for the visualiser. Everything else is standard library.

A path

from pathviz.maze import recursive_backtracker
from pathviz.search import astar

maze = recursive_backtracker(40, 40, braid=0.2)
path = astar((0, 0), (39, 39), maze)

braid is the fraction of dead ends removed, so 0 is a perfect maze with exactly one route between any two cells, and 1 is a maze with no dead ends at all.

Every algorithm has a _steps twin that yields one Step per expansion instead of returning a path. You write the loop, so what gets drawn is entirely up to you:

from pathviz.maze import recursive_backtracker
from pathviz.search import astar_steps, trace_path
from pathviz.visualiser import Visualiser

maze = recursive_backtracker(60, 60, braid=0.2)
start, end = (0, 0), (59, 59)

vis = Visualiser(maze)
vis.draw_maze()

for step in astar_steps(start, end, maze):
    vis.fill_cell(step.current, "Blue")
    vis.present()

for coord in trace_path(step.predecessors, end):
    vis.fill_cell(coord, "Orange")
vis.present()
vis.sleep(2000)

Drawing writes to a surface and nothing appears until present(), so one frame can be built from as many fill_cell calls as you like.

A Step carries current, discovered (the cells first reached this expansion), and live references to the search's own distances and predecessors. Reading them is free, but they mutate as the search runs, so copy anything you want to keep.

It also carries elapsed, the seconds spent searching so far. That counts only the search's own work, not the time your loop spends drawing between steps, so it stays meaningful while animating:

for step in astar_steps(start, end, maze):
    ...
print(f"{len(step.distances)} cells reached in {step.elapsed * 1000:.1f}ms")

Your own algorithm

Nothing in pathviz requires a Step. Yield whatever you measure and draw it however you want. The visualiser only ever sees coordinates and colours:

from collections import deque

def bfs(start, end, adjacency_list):
    queue, seen = deque([start]), {start}
    while queue:
        current = queue.popleft()
        yield current, len(queue)          # your own shape
        if current == end:
            return
        for neighbour in adjacency_list[current]:
            if neighbour not in seen:
                seen.add(neighbour)
                queue.append(neighbour)

for current, fringe_size in bfs(start, end, maze):
    vis.fill_cell(current, (0, min(fringe_size * 8, 255), 120))
    vis.present()

The same is true going the other way: any dict[node, set[node]] works as input, so astar and dijkstra will run on a graph that has nothing to do with a grid.

Modules

Module What it does Depends on
pathviz.graph GridGraph, used to build an adjacency list stdlib only
pathviz.maze recursive_backtracker, fully_connected pathviz.graph
pathviz.search dijkstra, astar, their _steps twins, trace_path stdlib only
pathviz.visualiser Visualiser, draws mazes, cells and numbers pygame

Nothing is re-exported from the top level, so importing one module doesn't drag in the others. pathviz.search imports nothing but the standard library, and code that never touches pathviz.visualiser never loads pygame.

Both import forms work, whichever reads better where you are:

from pathviz.search import astar          # astar(...)
from pathviz import search                # search.astar(...)

Examples

python examples/animate.py    # watch A* and Dijkstra solve a maze
python examples/runtime.py    # compare their work and timing, no window

Metadata

Release files for pathviz 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pathviz 0.3.0
File Size Uploaded
pathviz-0.3.0.tar.gz 10.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pathviz 0.3.0
File Interpreter ABI Platform
pathviz-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.1 kB

Release files / pathviz-0.3.0.tar.gz

Download URL pathviz-0.3.0.tar.gz
Size 10.0 kB
Tags Source
SHA-256 checksum
How to use checksums
32840b252235650de964420af85ce0d1abf97068037ba32fc83accf22f601b06
BLAKE2b-256 checksum
How to use checksums
caca3df1f2e1c3700314dcc0493a21eee5382412887dc29d6611ef7a53916b4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release files / pathviz-0.3.0-py3-none-any.whl

Download URL pathviz-0.3.0-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4762a9576202ca6a9649ccc6407d7dc5d6dd38a4d2477cde5c3e012d4f7c5cb
BLAKE2b-256 checksum
How to use checksums
0b16e693cd1e15be9819140a9306abbf856d5307e06ece4c33d204d39c6d3130
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page