An interactive educational tool for visualizing pathfinding algorithms β understand not just what the algorithm does, but why it makes each decision. Featuring a Feynman-style Insight panel, AI-powered summaries, playback controls, and a 7-slide onboarding tutorial.
- π― 8 Pathfinding Algorithms β Dijkstra, A*, Greedy Best-first, Swarm, Convergent Swarm, Bidirectional Swarm, BFS, DFS
- π§± Interactive Grid β Click to draw walls, hold
Wto place weighted nodes - π¨ 7 Maze Generators β Recursive division (horizontal/vertical skew), random walls, random weights, staircase, and blank grid
- β‘ 3 Speed Modes β Fast, Average, Slow
- π Step-by-Step Insight Panel β Real-time Feynman-style explanations of each algorithm decision: node selection reason, cost breakdowns (g/h/f), neighbor evaluation, frontier size, and visited count
- π‘ Feynman Tooltips β
?icons throughout the Insight panel explain every concept in beginner-friendly language - π€ AI-Powered Summary β 5-sentence beginner-friendly run summary via server-side OpenAI integration (with deterministic fallback)
- βοΈ Weight Slider β Experiment with cost values (0β50) in the sidebar
- π Results Bar β Post-run display of Path Cost, Length, and Visited count
- π "Why This Path?" β Weight impact analysis showing detour costs, efficiency rating, and counterfactual comparisons
βΆοΈ Playback Controls β Pause / Resume / Step Forward during Average and Slow speed modes- π 7-Slide Onboarding Tutorial β Animated walkthrough with keyboard navigation and accessibility (ARIA, focus trap)
- π§© Maze Selector Onboarding β Card-grid modal to pick a maze pattern after the tutorial
- π Algorithm Comparison Modal β Side-by-side table of all 8 algorithms covering optimality, completeness, complexity, and per-algorithm detail modals with pseudocode
- βΉοΈ Algorithm Info Modals β Navbar algorithm names open informational modals (not algorithm selectors)
- π Two-Tab Sidebar β "Controls" tab for settings, maze, weight, actions, history, and legend; "Insight" tab for live algorithm analysis
- πΎ Run History β Save last 5 runs in localStorage with full board state restoration
- π Replay β Re-animate a saved run
- ποΈ Manage β Delete individual saved runs
- Node.js >= 18
- npm or yarn
# Clone the repository
git clone https://github.com/your-username/Pathfinding-Visualizer.git
cd Pathfinding-Visualizer
# Install dependencies
npm install
# Copy environment template
cp .env.example .env
# Start the server (with nodemon auto-reload)
npm startOpen http://localhost:1337 in your browser.
| Command | Description |
|---|---|
npm start |
Start dev server with nodemon (port 1337) |
npm run build:client |
Bundle client JS via Browserify |
npm run watch |
Watch mode β auto-rebuild bundle on file changes |
npm test |
Run automated tests for algorithm behaviour, controls, persistence, fallback, explanation logic, and schema integrity |
- Get an API key from OpenAI Platform
- Edit
.envfile:OPENAI_API_KEY=sk-your-actual-key-here - Restart the server
Without an API key, the app uses deterministic fallback explanations (still fully functional!).
- Onboarding Tutorial β A 7-slide animated walkthrough appears on first visit, introducing concepts like the grid, algorithms, obstacles, and controls. Navigate with keyboard arrows or on-screen buttons. Click "Skip intro" to dismiss.
- Maze Selector β After the tutorial, a card-grid modal lets you pick a maze pattern (recursive division, random walls, staircase, etc.) or start with a blank grid.
- Set Start/Target β Drag the green (start) and red (target) nodes to reposition
- Draw Walls β Click and drag on empty cells
- Draw Weights β Hold
W+ click (only affects weighted algorithms) - Adjust Weight Value β Use the Weight Slider (0β50) in the sidebar Controls tab
- Generate Mazes β Use the Maze dropdown in the sidebar Controls tab
- Select Algorithm β Choose from the playback pod dropdown at the bottom of the screen
- Set Speed β Choose Fast / Average / Slow from the speed dropdown
- Visualize! β Click the "Visualize!" button
Note: Clicking algorithm names in the navbar opens informational modals (with pseudocode and details), not algorithm selection. Algorithm selection is done via the playback pod dropdown.
- The Insight tab (sidebar) updates live with:
- Current step number and node coordinates
- Cost breakdown (g/h/f values)
- "What's Happening?" β natural-language explanation of the current decision
- Frontier size and visited count metrics
- Playback Controls (Pause / Resume / Step Forward) appear in Average and Slow speed modes
- Results Bar shows Path Cost, Length, and Visited count
- "Why This Path?" renders a weight impact analysis in the Insight tab
- AI Summary auto-requests from the server (or shows fallback text)
- Run auto-saved to History (visible in the sidebar Controls tab)
- Drag endpoints β instant recalculation (no re-animation needed)
- Clear Path / Clear Walls / Clear Board buttons in the sidebar
- Browse History β Load a past run to restore full board state, or Replay to re-animate
| Algorithm | Optimal | Heuristic | Description |
|---|---|---|---|
| Dijkstra's | β | β | The classic; guarantees shortest path |
| A Search* | β | β | Best overall; uses heuristic for speed |
| Greedy Best-first | β | β | Fast but may not find shortest path |
| Swarm | β | β | Blend of Dijkstra and A* (see below) |
| Convergent Swarm | β | β | Faster, more heuristic-heavy Swarm |
| Bidirectional Swarm | β | β | Swarm from both ends |
| Algorithm | Optimal | Description |
|---|---|---|
| Breadth-first Search | β | Level-by-level exploration |
| Depth-first Search | β | Goes deep first; can find very long paths |
| Variable | Required | Default | Description |
|---|---|---|---|
OPENAI_API_KEY |
No | - | OpenAI API key for AI explanations |
PORT |
No | 1337 | Server port |
The algorithm uses this cost formula for weighted algorithms:
Edge Cost = Base (1) + Turn Penalty (0-2) + Node Weight (0-50)
| Turn Type | Penalty |
|---|---|
| Straight | +0 |
| 90Β° turn | +1 |
| 180Β° turn (backtrack) | +2 |
Note: Turn penalties are used in the internal search logic. However, the results-bar Path Cost display sums base cost + node weights only, and does not include turn penalties.
Generate an AI explanation for a completed pathfinding run.
- Rate Limit: 30 requests per 15-minute window per IP
- Security: Protected by Helmet (CSP headers) and express-rate-limit
Request Body:
{
"algorithmKey": "dijkstra",
"meta": {
"algorithmFamily": "weighted",
"guaranteesOptimal": true,
"usesHeuristic": false,
"complete": true,
"selectionRule": "Always expand the node with the lowest total cost found so far.",
"bestFor": "Finding guaranteed shortest paths in weighted graphs",
"weakness": "Explores in all directions equally"
},
"start": "row 10, col 5",
"target": "row 10, col 25",
"visitedCount": 846,
"pathLength": 38,
"directDistance": 20,
"detourSteps": 18,
"visitedPercent": 42,
"wallCount": 47,
"weightCount": 5,
"weightsInPath": 2,
"efficiency": 0.53,
"pathSample": ["row 10, col 5", "...", "row 10, col 25"]
}Response (AI enabled):
{
"explanation": "Dijkstra's Algorithm checked 846 cells (42% of the grid)...",
"source": "ai"
}Response (fallback):
{
"explanation": "The Dijkstra's Algorithm explored 846 cells (42% of the grid)...",
"source": "fallback"
}If no API key is configured or the OpenAI call fails,
sourcewill be"fallback"with a deterministic 5-sentence explanation.
# Run all unit tests
npm test
# Expected pass lines include:
# pathfindingAlgorithmsBehavior tests passed.
# animationController tests passed.
# runPersistence tests passed.
# aiExplainFallback tests passed.
# weightImpactAnalyzer tests passed.
# algorithmDescriptions schema tests passed.- Grid renders correctly on page load
- Tutorial displays and can be skipped
- Maze onboarding modal appears after tutorial
- Can draw walls and weights
- Can drag start/target nodes
- Weight slider updates weight value (0β50)
- All 8 algorithms run without errors
- Animation plays at all 3 speeds
- Playback controls (Pause/Resume/Step) work in Average/Slow modes
- Insight panel updates live during animation
- Results bar shows Path Cost, Length, Visited after run
- "Why This Path?" analysis renders in Insight tab
- AI Summary renders (or fallback text)
- History saves runs and displays in Controls tab
- Can load and replay a saved run
- Dragging endpoints after a run triggers instant recalculation
- Algorithm info modals open from navbar
- "Compare All" modal shows all 8 algorithms
- Clear Path / Walls / Board buttons work
- Maze generation works (all types from sidebar dropdown)
pathfindingredesign/
βββ index.html # Single HTML entry point
βββ server.js # Express server + /api/explain + Helmet + rate limit
βββ package.json # Dependencies & scripts
βββ .env.example # Environment template
β
βββ docs/ # Documentation (15 files)
β βββ 00-context-and-vision.md
β βββ 01-product-requirements.md
β βββ 02-feature-spec-step-by-step-explanations.md
β βββ 03-feature-spec-history-localstorage.md
β βββ 04-feature-spec-path-cost-experimentation.md
β βββ 05-architecture-and-refactor-plan.md
β βββ 06-delivery-plan-testing-and-metrics.md
β βββ 08-current-codebase-analysis.md
β βββ 09-accessibility.md
β βββ 10-feature-spec-insight-feynman-tooltips.md
β βββ 11-research-report-implementation-plan.md
β βββ 12-project-planning-and-architecture-corrected.md
β βββ 13-high-level-system-architecture.md
β βββ conventional-commits-cheatsheet.md
β
βββ tests/
β βββ pathfindingAlgorithmsBehavior.test.js
β βββ animationController.test.js
β βββ runPersistence.test.js
β βββ aiExplainFallback.test.js
β βββ weightImpactAnalyzer.test.js
β βββ algorithmDescriptionsSchema.test.js
β
βββ public/
βββ browser/
β βββ board.js # Main controller (Board constructor)
β βββ node.js # Node data model
β βββ getDistance.js # Turn-aware direction/distance utility
β βββ bundle.js # Browserify output (do not edit)
β β
β βββ pathfindingAlgorithms/
β β βββ astar.js
β β βββ weightedSearchAlgorithm.js
β β βββ unweightedSearchAlgorithm.js
β β βββ bidirectional.js
β β βββ testAlgorithm.js
β β
β βββ mazeAlgorithms/
β β βββ recursiveDivisionMaze.js
β β βββ otherMaze.js
β β βββ otherOtherMaze.js
β β βββ simpleDemonstration.js
β β βββ stairDemonstration.js
β β βββ weightsDemonstration.js
β β
β βββ animations/
β β βββ animationController.js # Pause / Resume / Step controls
β β βββ launchAnimations.js # Timed animation sequences
β β βββ launchInstantAnimations.js # Synchronous (instant) animation
β β βββ mazeGenerationAnimations.js
β β
β βββ utils/
β βββ aiExplain.js # fetch POST /api/explain
β βββ algorithmDescriptions.js # Algorithm metadata registry
β βββ algorithmCompare.js # Comparison modal logic
β βββ algorithmModal.js # Per-algorithm info modal
β βββ explanationTemplates.js # Feynman-style text templates
β βββ gridMetrics.js # Pure grid analysis functions
β βββ historyStorage.js # localStorage CRUD for runs
β βββ historyUI.js # Run history cards + replay
β βββ mazeSelector.js # Maze onboarding card-grid
β βββ runSerializer.js # Board state β JSON serializer
β βββ weightImpactAnalyzer.js # "Why This Path?" analysis
β
βββ styling/
βββ cssBasic.css # Main stylesheet
βββ cssPokemon.css # Alternate theme
flowchart LR
user["User"]
subgraph browser["Browser App"]
direction LR
ui["UI"]
board["Board Controller"]
algo["Algorithms + Visualization"]
end
store[("localStorage<br/>history + sidebar state")]
api["Express API"]
llm["OpenAI API"]
user -->|"interact"| ui
ui --> board
board -->|"run"| algo
board <-->|"save/load"| store
board -->|"POST /api/explain"| api
api --> llm
api -->|"AI summary"| board
Main logic runs in the browser. The server is only used for AI summaries and static serving.
- Browser is where the app mainly runs.
Board Controlleris the central coordinator.- History stays in
localStorage, and AI goes through Express.
Contributions are welcome! Please read the documentation in the /docs folder before making changes. The project uses conventional commits β see docs/conventional-commits-cheatsheet.md for reference.
ISC License
The Swarm Algorithm is an algorithm that I β at least presumably so (I was unable to find anything close to it online) β co-developed with a good friend and colleague, Hussein Farah.
The algorithm is essentially a mixture of Dijkstra's Algorithm and A* Search; more precisely, while it converges to the target node like A*, it still explores quite a few neighboring nodes surrounding the start node like Dijkstra's.
The algorithm differentiates itself from A* through its use of heuristics: it continually updates nodes' distance from the start node while taking into account their estimated distance from the target node. This effectively "balances" the difference in total distance between nodes closer to the start node and nodes closer to the target node, which results in the triangle-like shape of the Swarm Algorithm.
We named the algorithm "Swarm" because one of its potential applications could be seen in a video-game where a character must keep track of a boss with high priority (the target node), all the while keeping tracking of neighboring enemies that might be swarming nearby.