Quote:Original post by Kylotan
The first thing I would do is to add a lookup table to see if a node is on the closed list. At the moment, imagine that you've explored half your 16x16 map, so there are about 128 nodes on the closed list if your map has plenty of obstacles. Every new node you explore generates 8 neighbours, and for each of those neighbours, you have to compare it with 128 nodes on the closed list. That's looping over 1024 existing nodes every time you investigate a new one. And it gets worse as the search approaches the goal and the closed list keeps growing. Really you want to get this to be an O(1) operation so that it's just 8 instant comparisons.
I'd probably just implement this lookup table as an array of chars, (World_Width * World_Height / 8) in size. (Round up to nearest whole char.) std::fill it with zeros at the start, and set the bits as you add nodes to the closed list. If you have a little inline function to set and check individual bits, this is great.
Although to be honest, with a world as small as yours, you can just use an array of bools. But if your world gets bigger you'll probably find that packing it into a structure eight times smaller helps.
I did this and used an std::vector<bool> as 2D array. std::vector<bool> is "special" (if not somewhat evil) and will actually use only 1 bit per value, is this correct?
It's a lot faster now, even on a much older PC I don't actually see the lag shock anymore when placing new towers. Well ok, a little bit, when the path gets longer (and compiled without -O3).
Thanks! I'll have to think better about what data structures to use in the future :)