[solved] Moving player tile-to-tile (A* Pathfinding finally done)

Thus me wanting to make a new thread due to a new topic :o
Thanks, I’ll take a look at the link you posted :slight_smile: :point:

I followed the instructions on this A* Pathfinding guide for beginners. than created the process in Java (While debugging / fixing for hours to get the same result as instructed) and I came out with the same results as the guide for each step. (Which produce a list containing all the tiles that have been deemed walkable on this path)

I’m just stuck on the final step, “Obtaining the shortest path”.

My setup honestly performs ideal for me minus the checking of a gang of tiles when the destinations right around a corner 3 tiles away XD (Flood fill, posted in picture?)

Thanks for helping :slight_smile:
All I need to do is create a method that tracks a nodes children until the starting node is found.
(If that makes sense)

Like I said, the 5th section of Amit’s guide:


// The code to reconstruct paths is simple:

current = goal
path = [current]
while current != start:
   current = came_from[current]
   path.append(current)

It seems I’ll be able to fix the floodfill issue ^^ Hopefully ;D
Translating python to java and adaptable for my project should be fun ^
^

I think I’ll take a break from pathfinding in my current game, make a new project and make it a pathfinding system that’s easily implementable and adaptable.

Simple window no other spiffs in the way, window for rendering.

I want to actually get A* correct this time :3

Thanks for your help everyone :slight_smile:

Note that just flood fill + back trace is just breadth first search, A* is Dijkstra’s + greedy best first search. They’ll both yield fastest paths, but A* can handle weights and is faster to execute.
Just so you’re aware of the difference.

The way I managed to do this in my attempts was like this:

I set up a class that holds 3 values = x, y, next. When I loop over the “frontier” I get each location’s adjoining tiles and store the location in the next attribute.

Something like this:


location = queue.get(0);
newLocations = getAdjoiningTilesTo(location);
//  loop over newLocations and do
newLocations.get(0..size-1).next = location;

When you find your target you can loop over it like this:


location = targetTileFoundByPathfinding;

path = new ArrayList<LocationClass>();
while (location.next instanceof LocationClass) {

  path.add(location);
  location = location.next;

}

be aware though that you end up with the path in reverse :slight_smile:
(I know this isn’t great, but it works for me and optimise mine over time)

Hope this helps you!

[quote=“BurntPizza,post:26,topic:50874”]
Dijkstra handles weights just fine :point:

Oh, and A* is not guaranteed to yield the fastest path, as it is heavily biased to a path that lies on the line src→dst, it might not even visit the ‘instant portal’ only a few cells away (in the opposite direction). Dijkstra would handle this odd case just fine, at the cost of worse performance in the general case.

I was saying breadth first doesn’t do weights, could of said that more clearly.

If there are portals then instead of just using Euclidean distance from A to B for the heuristic, use (Euclidean distance from A to nearest portal) + (Euclidean distance from B to nearest portal) if that is shorter. Then A* won’t be incorrectly biased and will still guarantee the shortest path.

The portal example was an edge case. There can be an arbitrary number of shortcuts (areas with reduced weight) that A* simply doesn’t touch when it uses a non-zero H.

Fair enough. I suppose the point I really wanted to make was “use an appropriate heuristic and A* will work”.

If there are large zero-cost regions then it is tricky to define something more informative than h=0, but even at that limit A* just becomes Djikstra’s.

(Near)zero-cost is not required, the effect is already observable if we have a parallel dirt road and paved road. Let’s say the edges of the dirt road have cost 1.1 and the paved road has cost 0.9, all other edges (grass) have a cost of 2.0.


ORIGIN     |
   |       |
   |  <====|====== dirt road
   |       |
   |       |
   |       |  <=== paved road
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |       |
   |     TARGET

Dijkstra’s yielded path will follow the paved road. (takes a long time to compute)
A*'s yielded path will follow the dirt road. (takes a fraction of the time to compute)

I think we agree, though… :point:

I’m just going to use this pathfinding library instead of trying to create my first implementation of pathfinding on my own lol. (Burnt me out)

That’ll be my project today :slight_smile: Don’t feel like swapping my game project out because I can’t create a decent pathfinding system yet haha

Thanks for everyone’s help :slight_smile:

Hmm… actually I think we’re in disagreement on this bit. The heuristic distance I’d use is Manhattan0.9, because the most optimistic estimate of the distance is that there is some direct path by paved road. A using this will expand more nodes than if it used un-weighted Manhattan distance but it will be optimal again.

Regardless, at least the OP decided on a solution in the meantime ;D