Skip to content

rosenqvist/PathSim

Repository files navigation

PathSim logo

CI Release License: MIT Live Demo

PathSim is an interactive pathfinding visualizer built with C++ and Dear ImGui. Place walls, weighted terrain, waypoints, and one-way cells on a grid, then watch BFS, Dijkstra's, and A* solve it in real time and compare how each algorithm finds its way. The project is built with Clang and checked with clang-tidy, clang-format, and cppcheck.

Try it out: rosenqvist.github.io/PathSim

Key Features

Feature Description
Three algorithms BFS, Dijkstra's, and A* with a Run All option to compare side by side
Grid tools Walls, weighted cells (1–9), impassable cells, one-way cells, waypoints
Diagonal movement 8-directional movement with corner-cutting prevention
Maze generation Maze, Terrain, and Maze + Terrain modes that highlight algorithm differences
Playback controls Step-by-step, pause, resume, adjustable speed
Heatmap overlay Visualize exploration order from early (dark blue) to late (bright cyan)
Algorithm stats Node count, frontier size, path cost, compute time, with copy button
Keyboard shortcuts Full keyboard control for tools, playback, and brushes. Press H for a cheat sheet
Web build Runs in the browser via Emscripten and WebAssembly
Persistence Saves your current session state, so you can continue where you left off
Resizable grid 5×5 up to 100×100

Preview

Algorithm comparison

Run all three algorithms on the same grid and compare performance in the stats panel.

Algorithm comparison

Maze generation

Generate mazes, weighted terrain, or both to create scenarios where the algorithms diverge.

Maze generation

Heatmap overlay

See how each algorithm explores the grid, from early (dark blue) to late (bright cyan).

Heatmap overlay

Custom scenarios

Combine walls, impassable cells, one-way cells, waypoints, and weighted terrain to build complex grids.

Custom scenario

Why I Built This

At my part-time warehouse job I noticed that some picking routes were inefficient. Items that could be reached by a short direct path instead required the truck driver to loop back the way they came, turning what should be a natural progression through the aisles into unnecessary detours. I wanted to roughly compute how unoptimal these routes actually were, and to do that I needed a way to quickly mock up layouts and visualize different paths.

PathSim is that tool. It's built for drafting and experimentation, not production use. What started for me as way to sketch out warehouse routing turned into an exploration of how pathfinding algorithms work, why they make different choices, and how grid constraints like walls, weights, and one-way restrictions affect the paths they find.

How It Works

All three algorithms solve the same problem, finding a path from start to end, but they make different tradeoffs.

BFS uses a simple queue and expands outward layer by layer. It guarantees the fewest hops but is completely blind to cell weights, so on a weighted grid it often picks an expensive route that a cost-aware algorithm would avoid.

Dijkstra's uses a priority queue ordered by accumulated cost. It always expands the cheapest frontier node next, guaranteeing the optimal cost path. The tradeoff is that it explores in all directions equally, visiting many nodes that aren't toward the goal.

A* builds on Dijkstra's by adding a heuristic (Manhattan distance for cardinal movement, octile distance for diagonal) that estimates remaining cost to the goal. This biases expansion toward the goal, so it typically visits far fewer nodes while still guaranteeing optimal cost.

The three maze generation modes are designed to highlight these differences. Pure mazes show A*'s heuristic advantage. Pure terrain shows how Dijkstra's and A* avoid expensive cells while BFS plows straight through. Combined mode makes all three algorithms pick different paths.

Technical Decisions

Core/UI split. All algorithm and grid logic lives in a static library (pathsim_core) that has zero dependency on ImGui or any graphics code. The UI layer links against it but never leaks into it. This means the entire core can be tested with Catch2 in a headless CI environment without needing a window or GPU. It also made the Emscripten port straightforward since only the UI layer needed platform-specific changes.

Three maze modes. The three generation modes exist specifically to make the algorithms behave differently. On a pure maze with walls only and uniform weight, BFS and Dijkstra find the same path so A*'s heuristic is the only differentiator. On pure terrain with weights only and no walls, BFS is the odd one out because it ignores cost entirely. Combined mode is where all three diverge which makes the comparison actually interesting.

vcpkg for desktop, FetchContent for web. The desktop build uses vcpkg because it handles ImGui, GLFW and Catch2 reliably across platforms. The Emscripten build can't use vcpkg so it fetches ImGui with CMake's FetchContent and uses Emscripten's built-in GLFW port. This keeps the web build self-contained without maintaining a separate dependency system.

Notes to self: What I'd Do Differently

If I started over I'd separate core logic from UI on day one instead of refactoring it in later. The Emscripten port would have been much simpler with that boundary already in place. I'd also plan for cross-platform builds earlier since adapting the main loop for Emscripten meant rewriting it entirely to work with the browser's frame callback.

Building

Prerequisites

  • C++20 compiler (Clang, GCC, or MSVC)
  • CMake 3.25+
  • Ninja
  • vcpkg with VCPKG_ROOT environment variable set

vcpkg handles all dependencies (Dear ImGui, GLFW, Catch2) automatically.

Desktop

git clone https://github.com/rosenqvist/PathSim.git
cd PathSim

cmake --preset release
cmake --build build/release
./build/release/PathSim

Tests

Built with Catch2.

cmake --preset debug
cmake --build build/debug
ctest --test-dir build/debug --output-on-failure

Web (Emscripten)

Requires Emscripten installed. vcpkg is not needed for the web build.

emcmake cmake -B build/web -DCMAKE_BUILD_TYPE=Release
cmake --build build/web

Output is in build/web/web/. Open PathSim.html in a browser.

License

MIT

About

PathSim is an easy way to simulate and illustrate the most efficient route between two points by using pathfinding algorithms, such as A* and Dijkstra's.

Topics

Resources

License

Stars

Watchers

Forks

Contributors