| 12-17-2006, 06:09 AM | #1 | |
UPDATED - Version 2.30 Pathing Algorithm System by Ammorth Uses Linked Lists by iNfraNe and CSCache by Vexorian Special Thanks to Dalten Now Requires JASS Helper Features
Download Here (Version 2.30) This system is designed for an RPG with roads. It allows for easy scripting of units traveling to places, while staying on the roads (preserving the RPG style). I would assume it could be used for other uses, but this is the main intent.
Information on the A* algorithm can be found here This is a demo map. To install this system into your map, open this map with world editor and follow the instructions. Give credit if you use this in your map. |
| 12-17-2006, 11:52 AM | #2 |
I can see this being used in a TD. Haven't cheked it, but i'll rep you anyway. |
| 12-17-2006, 12:34 PM | #3 |
Reading about how the result works, I am afraid it will 'leak' strings. You could easily change the result method and use an array of integers instead. |
| 12-17-2006, 12:44 PM | #4 |
I'm sorry man, but using groups of units for looping and your other recursion stuff? This is crying out for the salvation of JASS. |
| 12-17-2006, 01:35 PM | #5 | ||
Quote:
Wow, I would never think string-leaking would be an issue... Okay, ill look into the integer arrays. Quote:
Whats wrong with the methods I use? The system runs extremely fast and has no noticeable lag while outputting the path. I did try make a JASS only version, but ran into problems with the "ForGroup" loop and local variables. I'll look over the system and see if I can remove the unitgroup loop. |
| 12-17-2006, 01:47 PM | #6 |
For Group's use a separate function, so ofcourse they don't transfer locals. Just use temp globals. Hell, you can usually even find suitable BJ globals, so you don't even need declare new ones. (Using globals does not "defeat the point of using JASS". If you think that the only advantage JASS has is locals, you're way off.) |
| 12-17-2006, 02:47 PM | #7 | |
Okay, I have removed the recursive trigger, the unitgroup loop and increased the maximum node limit to 300. The system is still in GUI though. I am only having one slight problem. Changing the output to integer arrays. The problem lies here. I could put all the nodes in a integer variable (like I'm doing with strings) but complex paths will most likely exceed the integer bit limit. I could also put all the values in a 2d array, but if the path is too long, it could exceed the array limit. (300 nodes x 30 node-paths = 9000 values = exceeds array limit) And ideas or can I just keep the string output? Edit: After some brains-storming, I have came up with 2 ideas (if I'm not allowed to stick with strings) 1) Push the system back to 90 nodes maximum, and then the nodes would always fit the integer array (90 x 90 = 8100 < 8192) 2) Use a gamecache as my array, and store all the values in there, under the proper headings. (there would be a lot of entries for the gamecache, which could be worse than the leaking strings (memory-wise). Ill do some tests and see which is worse. Opinnions? Edit 2: I ran a few tests about string leaks and gamecache memory usage. Here is the data. Click to see Data
As you can see, the increase in memory usage (from threads) is minute. As for a gamecache, it is less information, but the run-time is greater. |
| 12-17-2006, 07:48 PM | #8 |
Seems to work pretty slick, well done. |
| 12-17-2006, 08:23 PM | #9 |
Dijkstra's in GUI = incredible hack. Very nice. However it's impossible to understand, maintain or improve. - I very much doubt that gamecache is slower than strings - This is a good spot to use DARY's heap implementation - Since this is planar, you have a good distance heuristic for A* - It would be really good to cache the generated paths so that you slowly generate the all-pairs solution. Then this would scale well for units. - You can go past 90 to 127 nodes in an array for the full dense path matrix because it's symmetric (graph is undirected) |
| 12-17-2006, 09:33 PM | #10 | ||||||
Quote:
Quote:
Quote:
Another thing I would like to bring up is that using a gamecache would also leak strings because the categories and labels would have to be different. Look at my tests for example. One stores in multiple labels, the other only stores in 1. Quote:
Quote:
Quote:
|
| 12-17-2006, 11:15 PM | #11 |
gamecache can sometimes be the fastest solution, it is not all in the books sometimes a gamecache lookup is great cause it turns the big O to constant. So you used Dijkstras, hmnn now I am kind of scared to look at it since it is in GUI well pipes DARY is in the resources section should be in systems in the first or second page |
| 12-17-2006, 11:47 PM | #12 |
Dynamic array link in my sig. The path matrix I mean is one that maps current node to next node in path given some target. You would generate a path from it like this: JASS:function GetPath takes matrix pathmatrix, integer source, integer dest returns path loop exitwhen source == dest set source = getnextnodeinpath(pathmatrix,source,dest) if source == unknown then dijkstra(pathmatrix,source,dest) endif if source == no path exists then error out endif add source to path endloop endfunction As a side bonus using the path matrix representation lets you plug in various other pathing algorithms in instead of dijkstra. It takes full advantage of any extra path information an algorithm finds-in dijkstra's case, the shortest paths to all the nodes from the source. The dijkstra lists for 127 nodes will also fit into an 8192 element array. For your pathological end to end example, you have one list of length 1, one of 2, ... up to 126 or 127. Again that's (n^2+n)/2 total elements which <8191 for 127. |
| 12-18-2006, 04:11 AM | #13 |
Well, let me just say "I think I did it!" I have done the following: 1) Kept the 300 node maximum 2) Removed the use of strings in the output. The system now stores the output (as integers) in a gamcache under an array of labels, under the Unit ID of the called unit. 3) The system is still in GUI (Vexorian, you should take a look at it. I use a few conditional loops. )4) Included the movement system into the actual pathing system. This allows for full functionality of the system. I am cleaning up all unused variables, adding comments to the system, and double-checking all the code. PipeDream, my system can be symmetrical, but it also allows for "one-way" nodes. So a unit could go from node 001 to node 002, but not backwards to 001. The algorithm would then find a way around it. I hope this meets the standards of the mods! I'll see what you all think when I upload it. |
| 12-18-2006, 10:12 PM | #14 |
Could you perhaps apply this same logic to locations, hence creating a far smaller node and more usefulness. As of now, Warcraft has a maximum movespeed of 522. With a more precise system (far far more nodes) you could use a SetUnitPosition loop to move a unit faster than 522, but within the same path (because blizzard has some sort of shortest path algorithm as well, which tells a unit where to go when you click 'Move') |
| 12-18-2006, 10:18 PM | #15 | |
Quote:
You could modify the movement trigger to move the units in increments, instead of ordering the unit to move there. This would get taxing on the system though if you were to have many units being moved at once. The system does use GUI locations. You can make them as small as you want and as close as you want, You just are not able to exceed 300 nodes. The pathing system built into warcraft 3 finds absolute distances. This system can keep units on a path, between nodes. Hope that answers your question. |
