0

I developed a game in C++, and want to make sure everything is properly done. Is it a good solution to use a QHashIterator to check which item in the list has the lowest value (F-cost for pathfinding).

Snippet from my code:

 while(!pathFound){ //do while path is found

        QHashIterator<int, PathFinding*> iterator(openList);
        PathFinding* parent;
        iterator.next();
        parent = iterator.value();

        while(iterator.hasNext()){ //we take the next tile, and we take the one with the lowest value
            iterator.next();
            //checking lowest f value
            if((iterator.value()->getGcost() + iterator.value()->getHcost()) < (parent->getGcost() + parent->getHcost())){
                parent = iterator.value();
            }
        }

        if(!atDestionation(parent,endPoint)){ //here we check if we are at the destionation. if we are we return our pathcost.
            clearLists(parent);
            filllists(parent,endPoint);
        }else{
            pathFound = true;
            while(parent->hasParent()){
                 mylist.append(parent);
                 parent = parent->getParent();
            }
            pathcost = calculatePathCost(mylist);    //we calculate what the pathcost is and return it
        }
     }

If no? Are there better improvements?

I also found someting about the std::priority_queue. It this mutch better then a QHashIterator?

It's maybe not a problem with gameworld where there which are not big. But i'm looking for a suitable solution when the game worlds are big (like + 10000 calculations).Any marks?

Tim Dirks
  • 439
  • 1
  • 6
  • 17

1 Answers1

1

Here you basically scan the whole map to find the element that is the minimum one according to some values:

while(iterator.hasNext()){ //we take the next tile, and we take the one with the lowest value
    iterator.next();
    //checking lowest f value
    if((iterator.value()->getGcost() + iterator.value()->getHcost()) < (parent->getGcost() + parent->getHcost())){
        parent = iterator.value();
    }
}

All this code, if you had an stl container, for instance a map, could be reduced to:

auto parent = std::min_element(iterator.begin(), iterator.end(), [](auto& lhs, auto& rhs)
  { lhs.value()->getGcost() + lhs.value()->getHcost()) < (rhs.value()->getGcost() + rhs.value()->getHcost() }

Once you have something easier to understand you can play around with different containers, for instance it might be faster to hold a sorted vector in this case. )

Your code does not present any obvious problems per se, often performance gains are not conquered by optimizing little loops, it's more on how you code is organized. For instance I see that you have a lot of indirections, those cost a lot in cache misses. Or if you have to always find the minimum element, you could cache it in another structure and you would have it at a constant time, all the time.

dau_sama
  • 4,247
  • 2
  • 23
  • 30
  • It's maybe a stuppid question, but what do you mean by indirections? – Tim Dirks Aug 17 '15 at 16:07
  • I was referring to iterator.value(), assuming that this method is a pointer to some other structure, but I guess it's part of the Qt API, so there should not be a problem. – dau_sama Aug 17 '15 at 16:13
  • the stl container you wrote it not possible to use it in that way. I should remove the Qhashiterator then? And make only use of the STL container? – Tim Dirks Aug 17 '15 at 16:19
  • `QHash` exposes STL iterators. All Qt containers do. In that sense, it "is" a STL iterator. :) All that makes something "a STL iterator" is conformance with necessary concepts. `QHash` does it. – Kuba hasn't forgotten Monica Aug 17 '15 at 16:27
  • So it's not a bad chose to use a QHash iterator? I also used a QList for inserting only she nodes that I need. Because a QList is slow in inserting items but fast in reading them out. Which i need later more in my game. – Tim Dirks Aug 17 '15 at 17:06
  • @TimDirks A `QList` might be slow for two reasons: 1. It makes a copy of the item you insert, because it doesn't offer the emplacement/move mechanisms available in C++11 yet. 2. It has to copy the internal pointer array as it grows. ### To work around 2, you can `reserve` space for a number of items. To work around 1, use `std::list` and move/emplacement API that doesn't copy elements. – Kuba hasn't forgotten Monica Aug 17 '15 at 17:21
  • Which items are then better then QList? Using a sorted vector like @dau_sama said? – Tim Dirks Aug 17 '15 at 17:29
  • @TimDirks You have to measure the performance first. If you require a sorted data structure, there is plenty of that available that would be modern, C++11 code. – Kuba hasn't forgotten Monica Aug 17 '15 at 18:02