I tested this in the latest SVN update (Oct 23, 2014) and found that my LRM platoon of infantry moved strangely. Every time I clicked on a hex they would move next to that hex and then turn and try to move into the hex I originally wanted. I've attached a picture of it. I only clicked on the blue highlighted hex.
I can reproduce this issue. It's happening in the A* path planner that Saginatio recently added.
Try turning the infantry first then moving them. Ran across this once, thought it was a fluke as it didn't happen again so never reported it.
There are definitely work arounds that you can do to get it to work. I generally found that clicking the hex after the hex you wanted to go to would work (but not always).
It looks like A* is returning the wrong path for some reason. I didn't dig through the code to figure out why.
I'll look into it.
My first guess is that ShortestPathFinder is returning the shortest path measured in mp used; and if two separate paths are equal then it returns the one that travels most hexes. This behavior might be a bit counterintuitive but allows for smart obstacle avoiding.
What probably happens in the test case is that a path '0316->0415'.getMPUsed() returns 0 , path '0316->0315'.getMpUsed() returns 1 and path '03116->0415->0315' returns 1. Therefore path '03116->0415->0315' wins.
Problem is that mechanics behind getMpUsed are well obfuscated:| Santa Claus, I would wish for a nicely encapsulated class MovePathCostCalculator :) And a MovePathValidator too.
Ok, after a bit raw debugging I found out the cause of this bug:
For A* to work faster I had to make some assumptions about .getMpUsed() function. Precisely I assumed that moving from one hex to another always costs at least 1mp. This assumption is correct according to rule books, but in MM implementation there's an exception. A 0mp infantry has the ability to make 0mp moves (which is imo an unnecessary complication). This exception from the rules breaks my A* algorithm.
There are two possibilities:
1) fix the .getMPUsed method and pray it doesn't break anything else.
2) turn off A* for 0mp Infantry and use Dijkstra instead.
I chose 2) since it is safer and faster to code. Although in the future a proper refactoring of MovePath is needed. A refactoring that includes separating data from logic.
I'll commit my changes once I find my svn password :|
Last edit: saginatio 2014-10-30
Subversion: Committed revision [r11328].
Related
Commit: [r11328]
Last edit: Nicholas Walczak 2014-10-30
As a proof that getMPUsed is bugged check out this screencap: