Advertisement
DocteurMarsonge

Untitled

Sep 22nd, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <set>
  4. #include <cstdlib>
  5. #include <map>
  6. #include <chrono>
  7.  
  8. using namespace std;
  9. using namespace std::chrono;
  10.  
  11. struct tile {
  12.     int x;
  13.     int y;
  14.     int cost;
  15.     int distGoal;
  16.     int mapWidth; //we need to stock that so our < operator works properly
  17.     bool operator<(const tile& t2) const
  18.     {
  19.         if(distGoal!=t2.distGoal){
  20.             return distGoal < t2.distGoal;
  21.         }
  22.         else{
  23.             return abs(x+(mapWidth*y)) < abs(t2.x+(mapWidth*t2.y));    
  24.         }
  25.     }  
  26.     bool operator==(const tile& t2) const
  27.     {
  28.         return (x == t2.x && y == t2.y);
  29.     }
  30. };
  31.  
  32.  
  33.  
  34. int FindPath(const int nStartX, const int nStartY,
  35.              const int nTargetX, const int nTargetY,
  36.              const unsigned char* pMap, const int nMapWidth, const int nMapHeight,
  37.              int* pOutBuffer, const int nOutBufferSize);
  38.  
  39. int main(){
  40.  
  41.  
  42.     const unsigned char pMap[] = {1,1,1,1,1,1,0,0,0
  43.                                  ,0,1,0,1,0,1,1,1,1
  44.                                  ,0,1,1,1,0,0,0,0,1};
  45.     int pOutBuffer[12];
  46.     int pathLength;
  47.     high_resolution_clock::time_point t1 = high_resolution_clock::now();
  48.     for(int i =0;i<100000;i++){
  49.         pathLength = FindPath(0,0,8,2,pMap,9,3,pOutBuffer,12);
  50.     }
  51.     high_resolution_clock::time_point t2 = high_resolution_clock::now();
  52.  
  53.     auto duration = duration_cast<microseconds>( t2 - t1 ).count();
  54.  
  55.     cout << duration << endl;  
  56.     for(int i = 0; i<pathLength; i++){
  57.         cout << pOutBuffer[i] << " ";
  58.     }
  59.    
  60.      
  61.    
  62. }
  63.  
  64. void buildPath(map<tile,tile> cameFrom,tile cur,int* pOutBuffer);
  65.  
  66.  
  67. int FindPath(const int nStartX,const int nStartY,const int nTargetX,const int nTargetY,
  68.             const unsigned char* pMap,const int nMapWidth,const int nMapHeight,
  69.             int* pOutBuffer,const int nOutBufferSize){
  70.     struct tile start;
  71.     start.x = nStartX;
  72.     start.y = nStartY;
  73.     start.cost = 0;
  74.     start.distGoal = 0;
  75.     start.mapWidth = nMapWidth;
  76.     set<tile> openQueue, closeQueue;
  77.     map<tile,tile> cameFrom; //maps a tile with the one to use to get to here
  78.     openQueue.insert(start);
  79.     while(!openQueue.empty()){
  80.         struct tile cur = *(openQueue.begin());
  81.         closeQueue.insert(cur);
  82.         if(cur.cost > nOutBufferSize){ //this tile is the less costly. If it's above limits, stop
  83.             return -1;    
  84.         }
  85.         if(cur.x == nTargetX and cur.y == nTargetY){ //we've reached the goal
  86.             buildPath(cameFrom,cur,pOutBuffer);
  87.             return cur.distGoal;
  88.         }
  89.         set<tile> neighbours;
  90.         for(int k=-1;k<2;k+=2){
  91.             if(!(cur.x+k < 0|| cur.x+k>=nMapWidth)){ //if we're out of bonds, there's nowhere to go
  92.                 int positionInMap = cur.x+k + (cur.y*nMapWidth);
  93.                 if(!(pMap[positionInMap] == 0)){ //if we can walk there
  94.                     struct tile neigh;
  95.                     neigh.x = cur.x+k;
  96.                     neigh.y = cur.y; //yum
  97.                     neigh.mapWidth = nMapWidth;
  98.                     neigh.cost = cur.cost + 1;
  99.                     neighbours.insert(neigh);
  100.                 }
  101.             }
  102.            
  103.             if(!(cur.y+k < 0 || cur.y+k>=nMapHeight)){ //if we're out of bonds, there's nowhere to go
  104.                 int positionInMap = cur.x + ((cur.y+k)*nMapWidth);
  105.                 if(!(pMap[positionInMap] == 0)){ //if we can walk there
  106.                     struct tile neigh;
  107.                     neigh.x = cur.x;
  108.                     neigh.y = cur.y+k;
  109.                     neigh.mapWidth = nMapWidth;
  110.                     neigh.cost = cur.cost + 1;
  111.                     neighbours.insert(neigh);
  112.                 }
  113.             }
  114.         }
  115.             for(auto n : neighbours)
  116.             {
  117.                 if(closeQueue.find(n) == closeQueue.end()){
  118.                     set<tile>::iterator it;                  
  119.                     it = openQueue.find(n);
  120.                     if(it == openQueue.end()){
  121.                         n.distGoal = abs(n.x - nTargetX) + abs(n.y - nTargetY) + n.cost;
  122.                         cameFrom.insert({n, cur});
  123.                         openQueue.insert(n);
  124.                     }
  125.                     else if((*it).cost <= n.cost){
  126.                         continue;      
  127.                     }
  128.                     else{
  129.                     }
  130.                    
  131.                    
  132.                }
  133.             }
  134.         openQueue.erase(cur);
  135.     }
  136.     return -1;
  137. }
  138.  
  139. void buildPath(map<tile,tile> cameFrom, tile cur, int* pOutBuffer){
  140.     int i = cur.distGoal - 1;
  141.     pOutBuffer[i] = cur.x + cur.y*cur.mapWidth;
  142.     map<tile,tile>::iterator it = cameFrom.find(cur);
  143.     while (it != cameFrom.end()){
  144.         i--;
  145.         if(i<0){
  146.             break;
  147.         }
  148.         cur = it->second;
  149.         pOutBuffer[i] = cur.x + cur.y*cur.mapWidth;
  150.         it = cameFrom.find(cur);
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement