Giter VIP home page Giter VIP logo

astar-algorithm-cpp's Introduction

astar-algorithm

Build Status

Summary

An efficient implementation in C++ of the A* algorithm, designed to be used in high performance realtime applications (video games) and includes an optional pool memory allocator.

It accompanies this A* tutorial: https://www.heyes-jones.com/astar.php

The A* algorithm is due to Hart, Nillson and Raphael. See https://ieeexplore.ieee.org/document/4082128.

This repository is dedicated to the memory of Nils Nilsson who sadly passed away in 2019.

Looking for a C# version? Checkout the companion repository astar-algorithm-csharp for a port by @scaryg

Star History

Star History Chart

Release notes

v1.2 Breaking changes! C++ 11 is now the minimum required C++ standard. User is now required to provide a Hash function for their Node type. Thanks to a contribution from @btdubs the closed list is now an unordered_set and this greatly speeds up the execution time of the algorithm. Check the included demo code for examples of the Hash implementation for various Node types.

v1.1 Code cleanup and final version that does not require C++11

v1.0 Initial release once API stable.

License

This software is released under the MIT License, see license.txt

Commercial Use

This software has been used in a number of AAA video games, which is an area of software that relies on efficiency and reliability. In addition it has been used in a number of academic and personal projects that require efficient search. Please

Commercial users of the code are encouraged to make a donation to http://www.unicef.org/ if they find this project useful.

Projects using this code

If you wish to be added to the list of known products/educational projects using the code please contact me.

Compilation

Enter the cpp folder and run make

Introduction

This implementation is intended to be simple to read yet fairly efficient. To build it you can compile, with any recent C++ compiler, the following files :

For 8-puzzle solver

  • 8puzzle.cpp
  • stlastar.h
  • optionally fsa.h

Command line

8puzzle with no arguments runs with one of the boards in the cpp file, you can select the one you want changing the conditional compiliation instructions. Or if you prefer pass in a board on the command line using digits for the tile positions, where zero is the space. The board runs from left to right, each row at a time:

8puzzle 013824765

For path finder

  • findpath.cpp
  • stlastar.h
  • optionally fsa.h

pathfind has no arguments. You can edit the simple map in pathfind.cpp and the start and goal co-ordinates to experiement with the pathfinder.

Fixed size allocator

FSA is just a simple memory pool that uses a doubly linked list of available nodes in an array. This is a very efficient way to manage memory. It has no automatic resizing, so you must account for the fact it will use a fixed block of memory per instance and will report an error when memory is exhausted.

As mentioned briefly in the tutorial you can enable and disable the faster memory allocation. This allocates a fixed size block of memory, so you have to specify this size with the astar constructor. You need to enlarge it if you hit an out of memory assert during the search.

Compatibility notes:

This version of the code requires any standards compliant C++ using std C++11

astar-algorithm-cpp's People

Contributors

btdubs avatar gitter-badger avatar hoshi10 avatar justinhj avatar scaryg avatar sergiosota avatar shubhamkashyap1601 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

astar-algorithm-cpp's Issues

Why consider the closed list like the openlist in function SearchStep?

Your code really help me a lot but I have a question that in the SearchStep() method, why do you consider the closed list like the open list. In other word, I think when the successor is in the CLOSED list, we should ignore it directly, but you try " if node_successor is on the CLOSED list but the existing one is as good or better then discard this successor and continue ".

Some improvements

Hi,

I made some improvements on this project and if you want to use some of them I can provide it. I had to do some experiments to analyze a new heuristic algorithm and so I implemented two different methods, one to generate the next state provided another state, and another one to generate a random() state. To avoid the usage of unsolvable states, I´ve created a method to check if the state is solvable or not. As I need to put the algorithm to execute several times I introduced a second argument with the number of repetitions and put all this in a loop. There are some modifications about the heuristics but it is related to my own experiments, but I can explain them if you wish.

How to deal with different sized objects in a pathfinding situation?

I'm working on a game that uses A-star (A*) for path finding but I've come to a point where by I have some objects that are larger than a single grid square.

I'm running on a grid of 16_16px. wall segments are 16_16 and so make a single square impassable. Some of my baddies are 32*32 and so they need to check that a gap is at least 2 grid square wide in order to be able to pass throguh it.

I can't simply make the grid 32_32 as the design requires thin walls (at 16px) and there are a couple of smaller baddies that only take up a single 16_16 square.

How do I implement this mutli-resolution environment? Is A-star still the correct tool to use?

Can't compile in VS2010 express

I made my own version of the node class and it wouldn't compile, so I tried to compile both example files and both give me this error:
h:\programming\c++\astar-algorithm-cpp-master\stlastar.h(60): error C2338: UserState must be derived from AStarState!
h:\programming\c++\astar-algorithm-cpp-master\8puzzle.cpp(569) : see reference to class template instantiation 'AStarSearch' being compiled with
[
UserState=PuzzleState
]

I didn't edit any of the files, is this a known issue?

question about results

Hi,

Thanks for the awesome code!

I have a question, this is the first A-Star I have ever implemented, and I'm getting these winding results
instead of a straight line - is this normal for A-Star?

https://i.imgur.com/g113sCK.png

note: entire map is initialized to a cost of 1

thanks again for any suggestions you might have

edit: with the entire map initialized to a cost of 0, I get this even stranger result : https://i.imgur.com/3UuJWLk.png

looking for it to be a straight line unless there are obstacles, any ideas?

C interferface

For those not using C++ a C interface would be useful.

FreeSolutionNodes() crash

Hi there!
My program crashes when I am calling FreeSolutionNodes() without any preparation (on clear algorithm object). I noticed this function doesn't check m_Start for existence. Also it was not initialized in constructors, so the value is unpredictable. I added initialization with zero pointer and

if( !m_Start )
return;

lines in function body. Now that works. Can you check if this is good solution, and if it is so, place it in code?

Thank you.

GoalDistanceEstimate is wrong

Hi

The GoalDistanceEstimate numbers are not euclidean distance, nor the actual distance as per google. I understand you have taken directly from Norwis's AIMA, and I could not find any clue any where how they arrive at these values. Can you please check?

stlastar.h:661: EnsureMenoryFreed: Assertion `m_AllocateNodeCount == 0' failed.

I recently always get this assertion failure.
I checked and seems the m_AllocateNodeCount fails with value -2
Do you have any suggestions? Thanks!

Update:
I think I have located where is the cause: I called FreeSolutionNodes() when I didn't get a solution...
This frees m_Start and m_Goal, with decreasing the m_AllocateNodeCount to -2.

But anyway m_Start/m_Goal is allocated by AllocateNode()
Shouldn't we free it? Thanks!

allocator

You should be careful about the memory alignment of the USER_TYPE

C++ headers shouldn't do `using namespace std;`

Using namespaces in headers is considered bad practice because they unconditionally and irreversibly pollute the global namespace of every consumer.

This leads to conflicts especially since the std namespace uses a lot of general terms that someone might want to use elsewhere, for example function and copy. The user in microsoft/STL#1881 was having issues with a library conflicting with the standard library specifically because of this line (the library is in the endian namespace while C++20 has an std::endian enum now):

using namespace std;

The source .cpp files, however, can keep doing using namespace std since it won't affect any other files.

Why is this 9 setted here

Why is this return 9 there?

int GetMap( int x, int y )
{
    if( x < 0 ||
         x >= MAP_WIDTH ||
         y < 0 ||
         y >= MAP_HEIGHT
         )
    {
        return 9;
    }
    return world_map[(y*MAP_WIDTH)+x];
}

It would be nice if I request a GetMap(8, 0) and the algorithm ignore it.

3D Map

How to use a 3D=2D(t) map with moving obstacles?

Bug in c# code

In c# code in AStarPathfinder.SortedAddToOpenList() field "inserted" is always "false".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.