|
| 1 | +# A* Algorithm C++ Implementation |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This project provides a clean, efficient, and header-only C++ implementation of the A* (A-Star) pathfinding algorithm. It is designed for high-performance applications like video games and includes an optional fixed-size memory allocator (`fsa.h`) to minimize memory fragmentation and allocation overhead. |
| 6 | + |
| 7 | +The core logic resides in `stlastar.h`, which uses C++ templates to work with any user-defined state class that satisfies the required interface. |
| 8 | + |
| 9 | +## Building and Running |
| 10 | + |
| 11 | +### Prerequisites |
| 12 | +* C++ compiler supporting C++11 (e.g., `g++`, `clang++`). |
| 13 | +* `make` utility. |
| 14 | + |
| 15 | +### Build Commands |
| 16 | +The project uses a `makefile` to manage builds. |
| 17 | + |
| 18 | +* **Build All:** |
| 19 | + ```bash |
| 20 | + make |
| 21 | + ``` |
| 22 | + This compiles the library examples and tests, producing the following executables: |
| 23 | + * `8puzzle`: Solves the 8-puzzle sliding tile game. |
| 24 | + * `findpath`: Finds a path on a simple grid map. |
| 25 | + * `minpathbucharest`: Solves the "classic" AI problem of finding the shortest path to Bucharest. |
| 26 | + * `tests`: Runs the unit tests. |
| 27 | + |
| 28 | +* **Run Tests:** |
| 29 | + ```bash |
| 30 | + make test |
| 31 | + ``` |
| 32 | + |
| 33 | +* **Clean Build:** |
| 34 | + ```bash |
| 35 | + make clean |
| 36 | + ``` |
| 37 | + |
| 38 | +### Running Examples |
| 39 | +* **8-Puzzle:** |
| 40 | + ```bash |
| 41 | + ./8puzzle [board_string] |
| 42 | + # Example: ./8puzzle 013824765 |
| 43 | + ``` |
| 44 | +* **Pathfinder:** |
| 45 | + ```bash |
| 46 | + ./findpath |
| 47 | + ``` |
| 48 | + |
| 49 | +## Development Conventions |
| 50 | + |
| 51 | +### Core Architecture |
| 52 | +* **`stlastar.h`**: The main header file containing the `AStarSearch` class template. This is a header-only library; simply include this file in your project. |
| 53 | +* **`fsa.h`**: A fixed-size block memory allocator used internally by `AStarSearch` to optimize node allocation. Can be toggled via `USE_FSA_MEMORY` in `stlastar.h`. |
| 54 | + |
| 55 | +### User State Interface |
| 56 | +To use the A* search, you must define a class (e.g., `MapSearchNode`) that represents a state in your search space. This class acts as a template argument to `AStarSearch` and **must** implement the following methods: |
| 57 | + |
| 58 | +```cpp |
| 59 | +class YourStateClass { |
| 60 | +public: |
| 61 | + // Heuristic estimate of distance to goal (e.g., Manhattan distance, Euclidean distance) |
| 62 | + float GoalDistanceEstimate(YourStateClass &nodeGoal); |
| 63 | +
|
| 64 | + // Returns true if this node is the goal |
| 65 | + bool IsGoal(YourStateClass &nodeGoal); |
| 66 | +
|
| 67 | + // Generates successors and adds them to the search |
| 68 | + // Implementation should call astarsearch->AddSuccessor(NewNode) for each valid move |
| 69 | + bool GetSuccessors(AStarSearch<YourStateClass> *astarsearch, YourStateClass *parent_node); |
| 70 | +
|
| 71 | + // Cost of moving from this node to the successor |
| 72 | + float GetCost(YourStateClass &successor); |
| 73 | +
|
| 74 | + // Returns true if this state is identical to rhs |
| 75 | + bool IsSameState(YourStateClass &rhs); |
| 76 | +
|
| 77 | + // Returns a hash of the state (required for std::unordered_set) |
| 78 | + size_t Hash(); |
| 79 | +}; |
| 80 | +``` |
| 81 | +
|
| 82 | +### Usage Pattern |
| 83 | +1. Instantiate `AStarSearch<YourStateClass> astarsearch;`. |
| 84 | +2. Create start and goal states. |
| 85 | +3. Call `astarsearch.SetStartAndGoalStates(start, goal)`. |
| 86 | +4. Loop `astarsearch.SearchStep()` until the state is `SEARCH_STATE_SUCCEEDED` or `SEARCH_STATE_FAILED`. |
| 87 | +5. Retrieve the path using `astarsearch.GetSolutionStart()`, `GetSolutionNext()`, etc. |
| 88 | +6. Call `astarsearch.FreeSolutionNodes()` and `astarsearch.EnsureMemoryFreed()` to clean up. |
| 89 | +
|
| 90 | +### Testing |
| 91 | +* Tests are located in `tests.cpp`. |
| 92 | +* Ensure all tests pass with `make test` before submitting changes. |
0 commit comments