void PathFinding::internalSearchPath(const QString &destination_map,const quint8 &destination_x,const quint8 &destination_y,const QString ¤t_map,const quint8 &x,const quint8 &y,const QHash<quint16,quint32> &items) { Q_UNUSED(items); QTime time; time.restart(); QHash<QString,SimplifiedMapForPathFinding> simplifiedMapList; //transfer from object to local variable { QMutexLocker locker(&mutex); simplifiedMapList=this->simplifiedMapList; this->simplifiedMapList.clear(); } //resolv the path if(!tryCancel) { QList<MapPointToParse> mapPointToParseList; //init the first case { MapPointToParse tempPoint; tempPoint.map=current_map; tempPoint.x=x; tempPoint.y=y; mapPointToParseList << tempPoint; QPair<quint8,quint8> coord(tempPoint.x,tempPoint.y); SimplifiedMapForPathFinding &tempMap=simplifiedMapList[current_map]; tempMap.pathToGo[coord].left << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_left,1); tempMap.pathToGo[coord].right << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_right,1); tempMap.pathToGo[coord].bottom << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_bottom,1); tempMap.pathToGo[coord].top << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_top,1); } QPair<quint8,quint8> coord; while(!mapPointToParseList.isEmpty()) { const MapPointToParse &tempPoint=mapPointToParseList.takeFirst(); SimplifiedMapForPathFinding::PathToGo pathToGo; if(destination_map==current_map && tempPoint.x==destination_x && tempPoint.y==destination_y) qDebug() << QStringLiteral("final dest"); //resolv the own point int index=0; while(index<1)/*2*/ { if(tryCancel) { tryCancel=false; return; } { //if the right case have been parsed coord=QPair<quint8,quint8>(tempPoint.x+1,tempPoint.y); if(simplifiedMapList.value(current_map).pathToGo.contains(coord)) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapList.value(current_map).pathToGo.value(coord); if(pathToGo.left.isEmpty() || pathToGo.left.size()>nearPathToGo.left.size()) { pathToGo.left=nearPathToGo.left; pathToGo.left.last().second++; } if(pathToGo.top.isEmpty() || pathToGo.top.size()>(nearPathToGo.left.size()+1)) { pathToGo.top=nearPathToGo.left; pathToGo.top << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_top,1); } if(pathToGo.bottom.isEmpty() || pathToGo.bottom.size()>(nearPathToGo.left.size()+1)) { pathToGo.bottom=nearPathToGo.left; pathToGo.bottom << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_bottom,1); } } //if the left case have been parsed coord=QPair<quint8,quint8>(tempPoint.x-1,tempPoint.y); if(simplifiedMapList.value(current_map).pathToGo.contains(coord)) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapList.value(current_map).pathToGo.value(coord); if(pathToGo.right.isEmpty() || pathToGo.right.size()>nearPathToGo.right.size()) { pathToGo.right=nearPathToGo.right; pathToGo.right.last().second++; } if(pathToGo.top.isEmpty() || pathToGo.top.size()>(nearPathToGo.right.size()+1)) { pathToGo.top=nearPathToGo.right; pathToGo.top << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_top,1); } if(pathToGo.bottom.isEmpty() || pathToGo.bottom.size()>(nearPathToGo.right.size()+1)) { pathToGo.bottom=nearPathToGo.right; pathToGo.bottom << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_bottom,1); } } //if the top case have been parsed coord=QPair<quint8,quint8>(tempPoint.x,tempPoint.y+1); if(simplifiedMapList.value(current_map).pathToGo.contains(coord)) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapList.value(current_map).pathToGo.value(coord); if(pathToGo.top.isEmpty() || pathToGo.top.size()>nearPathToGo.top.size()) { pathToGo.top=nearPathToGo.top; pathToGo.top.last().second++; } if(pathToGo.left.isEmpty() || pathToGo.left.size()>(nearPathToGo.top.size()+1)) { pathToGo.left=nearPathToGo.top; pathToGo.left << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_left,1); } if(pathToGo.right.isEmpty() || pathToGo.right.size()>(nearPathToGo.top.size()+1)) { pathToGo.right=nearPathToGo.top; pathToGo.right << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_right,1); } } //if the bottom case have been parsed coord=QPair<quint8,quint8>(tempPoint.x,tempPoint.y-1); if(simplifiedMapList.value(current_map).pathToGo.contains(coord)) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapList.value(current_map).pathToGo.value(coord); if(pathToGo.bottom.isEmpty() || pathToGo.bottom.size()>nearPathToGo.bottom.size()) { pathToGo.bottom=nearPathToGo.bottom; pathToGo.bottom.last().second++; } if(pathToGo.left.isEmpty() || pathToGo.left.size()>(nearPathToGo.bottom.size()+1)) { pathToGo.left=nearPathToGo.bottom; pathToGo.left << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_left,1); } if(pathToGo.right.isEmpty() || pathToGo.right.size()>(nearPathToGo.bottom.size()+1)) { pathToGo.right=nearPathToGo.bottom; pathToGo.right << QPair<CatchChallenger::Orientation,quint8/*step number*/>(CatchChallenger::Orientation_right,1); } } } index++; } coord=QPair<quint8,quint8>(tempPoint.x,tempPoint.y); if(!simplifiedMapList.value(current_map).pathToGo.contains(coord)) { #ifdef CATCHCHALLENGER_EXTRA_CHECK extraControlOnData(pathToGo.left,CatchChallenger::Orientation_left); extraControlOnData(pathToGo.right,CatchChallenger::Orientation_right); extraControlOnData(pathToGo.top,CatchChallenger::Orientation_top); extraControlOnData(pathToGo.bottom,CatchChallenger::Orientation_bottom); #endif simplifiedMapList[current_map].pathToGo[coord]=pathToGo; } if(destination_map==current_map && tempPoint.x==destination_x && tempPoint.y==destination_y) { tryCancel=false; QList<QPair<CatchChallenger::Orientation,quint8/*step number*/> > returnedVar; if(returnedVar.isEmpty() || pathToGo.bottom.size()<returnedVar.size()) if(!pathToGo.bottom.isEmpty()) returnedVar=pathToGo.bottom; if(returnedVar.isEmpty() || pathToGo.top.size()<returnedVar.size()) if(!pathToGo.top.isEmpty()) returnedVar=pathToGo.top; if(returnedVar.isEmpty() || pathToGo.right.size()<returnedVar.size()) if(!pathToGo.right.isEmpty()) returnedVar=pathToGo.right; if(returnedVar.isEmpty() || pathToGo.left.size()<returnedVar.size()) if(!pathToGo.left.isEmpty()) returnedVar=pathToGo.left; if(!returnedVar.isEmpty()) { if(returnedVar.last().second<=1) { qDebug() << "Bug due for last step"; return; } else { qDebug() << "Path result into" << time.elapsed() << "ms"; returnedVar.last().second--; emit result(returnedVar); return; } } else { qDebug() << "Bug due to resolved path is empty"; return; } } //revers resolv //add to point to parse { //if the right case have been parsed coord=QPair<quint8,quint8>(tempPoint.x+1,tempPoint.y); if(!simplifiedMapList.value(current_map).pathToGo.contains(coord)) { MapPointToParse newPoint=tempPoint; newPoint.x++; if(newPoint.x<simplifiedMapList.value(current_map).width) if(PathFinding::canGoOn(simplifiedMapList.value(current_map),newPoint.x,newPoint.y)) { QPair<quint8,quint8> point(newPoint.x,newPoint.y); if(!simplifiedMapList.value(current_map).pointQueued.contains(point)) { simplifiedMapList[current_map].pointQueued << point; mapPointToParseList << newPoint; } } } //if the left case have been parsed coord=QPair<quint8,quint8>(tempPoint.x-1,tempPoint.y); if(!simplifiedMapList.value(current_map).pathToGo.contains(coord)) { MapPointToParse newPoint=tempPoint; if(newPoint.x>0) { newPoint.x--; if(PathFinding::canGoOn(simplifiedMapList.value(current_map),newPoint.x,newPoint.y)) { QPair<quint8,quint8> point(newPoint.x,newPoint.y); if(!simplifiedMapList.value(current_map).pointQueued.contains(point)) { simplifiedMapList[current_map].pointQueued << point; mapPointToParseList << newPoint; } } } } //if the bottom case have been parsed coord=QPair<quint8,quint8>(tempPoint.x,tempPoint.y+1); if(!simplifiedMapList.value(current_map).pathToGo.contains(coord)) { MapPointToParse newPoint=tempPoint; newPoint.y++; if(newPoint.y<simplifiedMapList.value(current_map).height) if(PathFinding::canGoOn(simplifiedMapList.value(current_map),newPoint.x,newPoint.y)) { QPair<quint8,quint8> point(newPoint.x,newPoint.y); if(!simplifiedMapList.value(current_map).pointQueued.contains(point)) { simplifiedMapList[current_map].pointQueued << point; mapPointToParseList << newPoint; } } } //if the top case have been parsed coord=QPair<quint8,quint8>(tempPoint.x,tempPoint.y-1); if(!simplifiedMapList.value(current_map).pathToGo.contains(coord)) { MapPointToParse newPoint=tempPoint; if(newPoint.y>0) { newPoint.y--; if(PathFinding::canGoOn(simplifiedMapList.value(current_map),newPoint.x,newPoint.y)) { QPair<quint8,quint8> point(newPoint.x,newPoint.y); if(!simplifiedMapList.value(current_map).pointQueued.contains(point)) { simplifiedMapList[current_map].pointQueued << point; mapPointToParseList << newPoint; } } } } } /*quint8 tempX=x,TempY=y; QString tempMap=current_map; SimplifiedMapForPathFinding::PathToGo pathToGoTemp; simplifiedMapList[current_map].pathToGo[QPair<quint8,quint8>(x,y)]=pathToGoTemp;*/ } } //drop the local variable { QHash<QString,SimplifiedMapForPathFinding>::const_iterator k = simplifiedMapList.constBegin(); while (k != simplifiedMapList.constEnd()) { delete k.value().dirt; delete k.value().ledges; delete k.value().walkable; delete k.value().monstersCollisionMap; ++k; } } tryCancel=false; emit result(QList<QPair<CatchChallenger::Orientation,quint8> >()); qDebug() << "Path not found into" << time.elapsed() << "ms"; }
void PathFinding::internalSearchPath(const std::string &destination_map,const uint8_t &destination_x,const uint8_t &destination_y, const std::string ¤t_map,const uint8_t &x,const uint8_t &y,const std::unordered_map<uint16_t,uint32_t> &items) { Q_UNUSED(items); QTime time; time.restart(); std::unordered_map<std::string,SimplifiedMapForPathFinding> simplifiedMapList; //transfer from object to local variable { QMutexLocker locker(&mutex); simplifiedMapList=this->simplifiedMapList; this->simplifiedMapList.clear(); } //resolv the path if(!tryCancel) { std::vector<MapPointToParse> mapPointToParseList; //init the first case { MapPointToParse tempPoint; tempPoint.map=current_map; tempPoint.x=x; tempPoint.y=y; mapPointToParseList.push_back(tempPoint); std::pair<uint8_t,uint8_t> coord(tempPoint.x,tempPoint.y); SimplifiedMapForPathFinding &tempMap=simplifiedMapList[current_map]; tempMap.pathToGo[coord].left.push_back( std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_left,1)); tempMap.pathToGo[coord].right.push_back( std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_right,1)); tempMap.pathToGo[coord].bottom.push_back( std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_bottom,1)); tempMap.pathToGo[coord].top.push_back( std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_top,1)); } std::pair<uint8_t,uint8_t> coord; while(!mapPointToParseList.empty()) { const SimplifiedMapForPathFinding &simplifiedMapForPathFinding=simplifiedMapList.at(current_map); const MapPointToParse tempPoint=mapPointToParseList.front(); mapPointToParseList.erase(mapPointToParseList.cbegin()); SimplifiedMapForPathFinding::PathToGo pathToGo; if(destination_map==current_map && tempPoint.x==destination_x && tempPoint.y==destination_y) qDebug() << "final dest"; //resolv the own point int index=0; while(index<1)/*2*/ { if(tryCancel) { tryCancel=false; return; } { //if the right case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x+1,tempPoint.y); if(simplifiedMapForPathFinding.pathToGo.find(coord)!=simplifiedMapForPathFinding.pathToGo.cend()) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapForPathFinding.pathToGo.at(coord); if(pathToGo.left.empty() || pathToGo.left.size()>nearPathToGo.left.size()) { pathToGo.left=nearPathToGo.left; pathToGo.left.back().second++; } if(pathToGo.top.empty() || pathToGo.top.size()>(nearPathToGo.left.size()+1)) { pathToGo.top=nearPathToGo.left; pathToGo.top.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_top,1)); } if(pathToGo.bottom.empty() || pathToGo.bottom.size()>(nearPathToGo.left.size()+1)) { pathToGo.bottom=nearPathToGo.left; pathToGo.bottom.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_bottom,1)); } } //if the left case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x-1,tempPoint.y); if(simplifiedMapForPathFinding.pathToGo.find(coord)!=simplifiedMapForPathFinding.pathToGo.cend()) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapForPathFinding.pathToGo.at(coord); if(pathToGo.right.empty() || pathToGo.right.size()>nearPathToGo.right.size()) { pathToGo.right=nearPathToGo.right; pathToGo.right.back().second++; } if(pathToGo.top.empty() || pathToGo.top.size()>(nearPathToGo.right.size()+1)) { pathToGo.top=nearPathToGo.right; pathToGo.top.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_top,1)); } if(pathToGo.bottom.empty() || pathToGo.bottom.size()>(nearPathToGo.right.size()+1)) { pathToGo.bottom=nearPathToGo.right; pathToGo.bottom.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_bottom,1)); } } //if the top case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x,tempPoint.y+1); if(simplifiedMapForPathFinding.pathToGo.find(coord)!=simplifiedMapForPathFinding.pathToGo.cend()) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapForPathFinding.pathToGo.at(coord); if(pathToGo.top.empty() || pathToGo.top.size()>nearPathToGo.top.size()) { pathToGo.top=nearPathToGo.top; pathToGo.top.back().second++; } if(pathToGo.left.empty() || pathToGo.left.size()>(nearPathToGo.top.size()+1)) { pathToGo.left=nearPathToGo.top; pathToGo.left.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_left,1)); } if(pathToGo.right.empty() || pathToGo.right.size()>(nearPathToGo.top.size()+1)) { pathToGo.right=nearPathToGo.top; pathToGo.right.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_right,1)); } } //if the bottom case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x,tempPoint.y-1); if(simplifiedMapForPathFinding.pathToGo.find(coord)!=simplifiedMapForPathFinding.pathToGo.cend()) { const SimplifiedMapForPathFinding::PathToGo &nearPathToGo=simplifiedMapForPathFinding.pathToGo.at(coord); if(pathToGo.bottom.empty() || pathToGo.bottom.size()>nearPathToGo.bottom.size()) { pathToGo.bottom=nearPathToGo.bottom; pathToGo.bottom.back().second++; } if(pathToGo.left.empty() || pathToGo.left.size()>(nearPathToGo.bottom.size()+1)) { pathToGo.left=nearPathToGo.bottom; pathToGo.left.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_left,1)); } if(pathToGo.right.empty() || pathToGo.right.size()>(nearPathToGo.bottom.size()+1)) { pathToGo.right=nearPathToGo.bottom; pathToGo.right.push_back(std::pair<CatchChallenger::Orientation,uint8_t/*step number*/>(CatchChallenger::Orientation_right,1)); } } } index++; } coord=std::pair<uint8_t,uint8_t>(tempPoint.x,tempPoint.y); if(simplifiedMapForPathFinding.pathToGo.find(coord)==simplifiedMapForPathFinding.pathToGo.cend()) { #ifdef CATCHCHALLENGER_EXTRA_CHECK extraControlOnData(pathToGo.left,CatchChallenger::Orientation_left); extraControlOnData(pathToGo.right,CatchChallenger::Orientation_right); extraControlOnData(pathToGo.top,CatchChallenger::Orientation_top); extraControlOnData(pathToGo.bottom,CatchChallenger::Orientation_bottom); #endif simplifiedMapList[current_map].pathToGo[coord]=pathToGo; } if(destination_map==current_map && tempPoint.x==destination_x && tempPoint.y==destination_y) { tryCancel=false; std::vector<std::pair<CatchChallenger::Orientation,uint8_t/*step number*/> > returnedVar; if(returnedVar.empty() || pathToGo.bottom.size()<returnedVar.size()) if(!pathToGo.bottom.empty()) returnedVar=pathToGo.bottom; if(returnedVar.empty() || pathToGo.top.size()<returnedVar.size()) if(!pathToGo.top.empty()) returnedVar=pathToGo.top; if(returnedVar.empty() || pathToGo.right.size()<returnedVar.size()) if(!pathToGo.right.empty()) returnedVar=pathToGo.right; if(returnedVar.empty() || pathToGo.left.size()<returnedVar.size()) if(!pathToGo.left.empty()) returnedVar=pathToGo.left; if(!returnedVar.empty()) { if(returnedVar.back().second<=1) { qDebug() << "Bug due for last step"; return; } else { qDebug() << "Path result into " << time.elapsed() << "ms"; returnedVar.back().second--; emit result(current_map,x,y,returnedVar); return; } } else { returnedVar.clear(); qDebug() << "Bug due to resolved path is empty"; return; } } //revers resolv //add to point to parse { //if the right case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x+1,tempPoint.y); if(simplifiedMapForPathFinding.pathToGo.find(coord)==simplifiedMapForPathFinding.pathToGo.cend()) { MapPointToParse newPoint=tempPoint; newPoint.x++; if(newPoint.x<simplifiedMapForPathFinding.width) if(PathFinding::canGoOn(simplifiedMapForPathFinding,newPoint.x,newPoint.y) || (destination_map==current_map && newPoint.x==destination_x && newPoint.y==destination_y)) { std::pair<uint8_t,uint8_t> point(newPoint.x,newPoint.y); if(simplifiedMapForPathFinding.pointQueued.find(point)==simplifiedMapForPathFinding.pointQueued.cend()) { simplifiedMapList[current_map].pointQueued.insert(point); mapPointToParseList.push_back(newPoint); } } } //if the left case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x-1,tempPoint.y); if(simplifiedMapForPathFinding.pathToGo.find(coord)==simplifiedMapForPathFinding.pathToGo.cend()) { MapPointToParse newPoint=tempPoint; if(newPoint.x>0) { newPoint.x--; if(PathFinding::canGoOn(simplifiedMapForPathFinding,newPoint.x,newPoint.y) || (destination_map==current_map && newPoint.x==destination_x && newPoint.y==destination_y)) { std::pair<uint8_t,uint8_t> point(newPoint.x,newPoint.y); if(simplifiedMapForPathFinding.pointQueued.find(point)==simplifiedMapForPathFinding.pointQueued.cend()) { simplifiedMapList[current_map].pointQueued.insert(point); mapPointToParseList.push_back(newPoint); } } } } //if the bottom case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x,tempPoint.y+1); if(simplifiedMapForPathFinding.pathToGo.find(coord)==simplifiedMapForPathFinding.pathToGo.cend()) { MapPointToParse newPoint=tempPoint; newPoint.y++; if(newPoint.y<simplifiedMapForPathFinding.height) if(PathFinding::canGoOn(simplifiedMapForPathFinding,newPoint.x,newPoint.y) || (destination_map==current_map && newPoint.x==destination_x && newPoint.y==destination_y)) { std::pair<uint8_t,uint8_t> point(newPoint.x,newPoint.y); if(simplifiedMapForPathFinding.pointQueued.find(point)==simplifiedMapForPathFinding.pointQueued.cend()) { simplifiedMapList[current_map].pointQueued.insert(point); mapPointToParseList.push_back(newPoint); } } } //if the top case have been parsed coord=std::pair<uint8_t,uint8_t>(tempPoint.x,tempPoint.y-1); if(simplifiedMapForPathFinding.pathToGo.find(coord)==simplifiedMapForPathFinding.pathToGo.cend()) { MapPointToParse newPoint=tempPoint; if(newPoint.y>0) { newPoint.y--; if(PathFinding::canGoOn(simplifiedMapForPathFinding,newPoint.x,newPoint.y) || (destination_map==current_map && newPoint.x==destination_x && newPoint.y==destination_y)) { std::pair<uint8_t,uint8_t> point(newPoint.x,newPoint.y); if(simplifiedMapForPathFinding.pointQueued.find(point)==simplifiedMapForPathFinding.pointQueued.cend()) { simplifiedMapList[current_map].pointQueued.insert(point); mapPointToParseList.push_back(newPoint); } } } } } /*uint8_t tempX=x,TempY=y; std::string tempMap=current_map; SimplifiedMapForPathFinding::PathToGo pathToGoTemp; simplifiedMapList[current_map].pathToGo[std::pair<uint8_t,uint8_t>(x,y)]=pathToGoTemp;*/ } } //drop the local variable { for ( auto &n : simplifiedMapList ) { if(n.second.dirt!=NULL) { delete n.second.dirt; n.second.dirt=NULL; } if(n.second.ledges!=NULL) { delete n.second.ledges; n.second.ledges=NULL; } if(n.second.walkable!=NULL) { delete n.second.walkable; n.second.walkable=NULL; } if(n.second.monstersCollisionMap!=NULL) { delete n.second.monstersCollisionMap; n.second.monstersCollisionMap=NULL; } } } tryCancel=false; emit result(std::string(),0,0,std::vector<std::pair<CatchChallenger::Orientation,uint8_t> >()); qDebug() << "Path not found into " << time.elapsed() << "ms"; }