Introduction to A* (1997)
theory.stanford.edu
theory.stanford.edu
https://www.redblobgames.com/articles/noise/introduction.htm...
Amit's articles were online then, and definitely helped me think through these problems, and their main strength is just how visual the explanations all are. I'm pleased to see they're still online, being updated, and no doubt benefitting others, I know that personally Amit's effort was one of a number of things that has allowed me to be a full-time indie game developer all these years later.
1. First generation was to use a series of 'way points' that was created with the landscape/level generator itself. They were the basic 'paths of best flow' in a very broad sense. It was used when a player sent troops from one side of the map to the other. There was only 20-40 of these on a map.
2. Second generation used a much finer granularity that was a lookup of preprocessed surface normals on the terrain.
So, the tank/unit would look at the waypoints to know generally which way is the 'best ish' way, and use a finer grained one for the first and last mile.
We also used collision avoidance schemes so you could pass one group of vehicles 'thru' another and they'd miss one another in a logical way (ie small deviations left/right based upon own vs. other speed).
We ended up not using the 'one vehicle per square' technique that may RTS used at the time -- we didn't need to.
Take a look at the explanation and figures here: http://aigamedev.com/open/tutorials/theta-star-any-angle-pat... for more information.
I love well written clojure code
A* was probably one of the most fun projects I did back in school a few years ago. If anyone is interested, last winter I ported an old C#/Unity A* implementation of mine to Rust and compiled it to WebAssembly for a small demo. It was my first time trying out wasm and really getting into Rust.
Repo: https://github.com/jakedeichert/wasm-astar
Live demo: https://jakedeichert.github.io/wasm-astar/
https://www.gdcvault.com/play/1022094/JPS-Over-100x-Faster-t...
A* does well when it is given a graph of all the decision points that matter. An unweighted grid is full of locations where it doesn't matter — e.g. whether you go N,N,E or E,N,N or N,E,N. JPS searches for better decision points on unweighted grids. There are lots of other A* optimizations for unweighted grids (subgoal graphs, contraction hierarchies, differential heuristics, bucketed priority queues, etc.) — see Table 2 in this paper [1].
JPS is notable for using no precomputation, which is very useful when the map is changing often. If you can afford analyzing the grid ahead of time, you can build a much better graph than using the grid directly — the Tree entry listed in Table 2 takes 30 sec of precomputation to bring A* down to 0.029 ms on average, compared to JPS which takes 62.524 ms on average.
[1] https://www.aaai.org/ocs/index.php/SOCS/SOCS15/paper/view/11...
But what if instead of having infinite units of sight or 1 unit of sight, the subject could see for example 10 units ahead. This could give a similar path demonstrated in the second photo by the red line.
I later took a mechatronics class where we tried to implement A* on the microcontroller, which was a cool opportunity to see something theoretical in a physical way.
It was probably one of the most fun and satisfying projects I did at university, alongside coding my own implementation of the RIPv2 routing protocol and my embedded systems projects (the last of which was creating a bluetooth controlled car with a webcam on it, which required us to design and build the entire board around a provided microcontroller).
It was just so satisfying to implement something that just a couple of years prior was practically magic.
[1]: http://aimacode.github.io/aima-javascript/3-Solving-Problems...
[1] Chapter 17 http://www.gameaipro.com/GameAIPro/GameAIPro_Chapter17_Pathf...
[2] Slides https://www.movingai.com/GDC18/GDC18Bidir.pdf or if you have access to the GDC Vault there's a recording of the talk https://www.gdcvault.com/browse/gdc-18/play/1025071/Bidirect...