Skip to content

phucttg/pathfindingredesign

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

117 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pathfinding Visualizer

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.

License Node


✨ Features

Core Visualization

  • 🎯 8 Pathfinding Algorithms β€” Dijkstra, A*, Greedy Best-first, Swarm, Convergent Swarm, Bidirectional Swarm, BFS, DFS
  • 🧱 Interactive Grid β€” Click to draw walls, hold W to 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

Educational Tools

  • πŸ“– 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

Controls & Navigation

  • ▢️ 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

History & Replay

  • πŸ’Ύ Run History β€” Save last 5 runs in localStorage with full board state restoration
  • πŸ”„ Replay β€” Re-animate a saved run
  • πŸ—‘οΈ Manage β€” Delete individual saved runs

πŸš€ Getting Started

Prerequisites

  • Node.js >= 18
  • npm or yarn

Installation

# 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 start

Open http://localhost:1337 in your browser.

Development Commands

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

Enable AI Explanations (Optional)

  1. Get an API key from OpenAI Platform
  2. Edit .env file:
    OPENAI_API_KEY=sk-your-actual-key-here
    
  3. Restart the server

Without an API key, the app uses deterministic fallback explanations (still fully functional!).


πŸ“– Usage Guide

First-Time Experience

  1. 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.
  2. 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.

Configuring the Grid

  1. Set Start/Target β€” Drag the green (start) and red (target) nodes to reposition
  2. Draw Walls β€” Click and drag on empty cells
  3. Draw Weights β€” Hold W + click (only affects weighted algorithms)
  4. Adjust Weight Value β€” Use the Weight Slider (0–50) in the sidebar Controls tab
  5. Generate Mazes β€” Use the Maze dropdown in the sidebar Controls tab

Running an Algorithm

  1. Select Algorithm β€” Choose from the playback pod dropdown at the bottom of the screen
  2. Set Speed β€” Choose Fast / Average / Slow from the speed dropdown
  3. 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.

During Visualization

  • 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

After Visualization

  • 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

🧠 Algorithms

Weighted Algorithms

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

Unweighted Algorithms

Algorithm Optimal Description
Breadth-first Search βœ… Level-by-level exploration
Depth-first Search ❌ Goes deep first; can find very long paths

βš™οΈ Configuration

Environment Variables

Variable Required Default Description
OPENAI_API_KEY No - OpenAI API key for AI explanations
PORT No 1337 Server port

Cost Model

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.


πŸ”Œ API Reference

POST /api/explain

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, source will be "fallback" with a deterministic 5-sentence explanation.


πŸ§ͺ Testing

# 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.

Manual Testing Checklist

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

πŸ“ Project Structure

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

πŸ—οΈ Architecture

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
Loading

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 Controller is the central coordinator.
  • History stays in localStorage, and AI goes through Express.

🀝 Contributing

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.


πŸ“„ License

ISC License


πŸ’‘ About the Swarm Algorithm

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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors