Add stepwise A* search for visualizing pathfinding progress#25
Merged
Conversation
Adds Pathfinder.BeginStepwiseSearch, an educational/visualization API that runs the same A* search as GetPath but one expansion at a time. Each Tick() returns an immutable SearchStep snapshot with the accumulated searched area (open frontier + closed/expanded cells, each with its A* g/h/f scores) and, on success, the path. The single A* iteration is factored into a shared ExpandNext helper so the batch GetPath and the stepwise search run identical logic (no duplication), and GetPath's hot path is unchanged (ExpandNext is AggressiveInlining). The stepwise driver is a public nested Pathfinder.StepwiseSearch (IDisposable) that reuses the private algorithm internals rather than subclassing — Pathfinder is sealed and its internals are private. It pins the cell buffer for the search lifetime, so it must be disposed and locks the instance to a single active session. New public types: Pathfinder.StepwiseSearch, SearchStep, SearchNode, SearchState, SearchNodeState. Verified: dotnet build (0 errors) and the full test suite (115 passed, incl. 15 new stepwise tests). Docs added under docs/api and docs/guides/visualizing-search.md; README and CLAUDE.md updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a stepwise (tick-by-tick) variant of the A* search for displaying how the pathfinder works — an educational/visualization facility that does not replace or change
GetPath.Pathfinder.BeginStepwiseSearch(agent, from, to)returns a disposablePathfinder.StepwiseSearch. EachTick()performs a single cell expansion and returns an immutableSearchStepsnapshot containing:Open(frontier) orClosed(expanded), each with its A*g/h/fscores,Current(the cell expanded this tick),OpenCount/ClosedCount, andRunToCompletion()advances to the end in one call.Why this design
The request asked for a
Tick-style API that shows the flow without changing how the pathfinder works today and without duplicating code — and floated "a separate class that inherits fromPathfinder".Pathfinderissealedand its algorithm internals areprivate; inheriting would force unsealing it and exposing unsafe pointer internals asprotected. Instead the driver is a public nestedPathfinder.StepwiseSearch, which reuses every private helper directly.ExpandNext, called by both the batchGetPathloop and the stepwise search — so they run identical expansion logic and find the same path.ExpandNextisAggressiveInlining, keepingGetPath's hot path unchanged (a pure, behavior-preserving refactor; the existing 100 tests still pass).GCHandle) for the search lifetime so the open set's raw pointers stay valid across ticks — hence it isIDisposableand locks the instance to one active session (InvalidOperationExceptionon a second). Snapshots own plain arrays (no pooling) so they survive across ticks.The visualized
Pathis the raw A* path (no smoothing), followingPathResult's origin-excluded convention.New public types
Pathfinder.StepwiseSearch,SearchStep,SearchNode,SearchState,SearchNodeState.Verification
dotnet build src/mpath-source/Migs.MPath.sln— 0 errors.dotnet test …/Migs.MPath.Tests.csproj— 115 passed (100 existing + 15 new stepwise tests covering path equivalence withGetPath, monotonic accumulation, open/closed partitioning, failure on unreachable targets, origin==destination, idempotent/disposed ticks, the single-session guard, and argument validation).Docs
docs/api/pages:StepwiseSearch,SearchStep,SearchNode,SearchState(+ index).docs/guides/visualizing-search.md(+docs/README.mdindex).docs/api/Pathfinder.md,README.md, andCLAUDE.mdupdated for the new public surface and architecture.🤖 Generated with Claude Code