Advertisement
Guest User

Navigator.cpp

a guest
Feb 25th, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.79 KB | None | 0 0
  1. #include "Navigator.h"
  2. #include "Debugger.h"
  3. #include "StringHelper.h"
  4. //#include "MapWindow.h"
  5.  
  6. using namespace std;
  7.  
  8. Navigator::Navigator(MapWindow * mapWindow) {
  9.     world = mapWindow;
  10. }
  11.  
  12. Path Navigator::findPath(Vector2 startpos, Vector2 destinationPos) {
  13.     Debugger::print("Starting with pos:" + toString(startpos.x) + "," + toString(startpos.y) + "\n");
  14.     //initialization
  15.     //Define variables
  16.     vector<Node> nodes;//all the frontier nodes with more paths to explore
  17.     int x = startpos.x, y = startpos.y;
  18.     //If already at goal, ezpz
  19.     if (x == (int)(destinationPos.x) && y == (int)(destinationPos.y)) {
  20.         nodes.push_back(Node((int)destinationPos.x, (int)destinationPos.y, 0));
  21.         return Path(nodes);
  22.     }
  23.     //more variables
  24.     vector<vector<Node>> referenceNodes; //For storing where the node was reached from
  25.     vector<vector<bool>> temp;
  26.     flags = temp;
  27.     for (size_t y = 0; y < world->getMap()->tiles.size(); y++) {
  28.         vector<bool> tempb;
  29.         vector<Node> tempn;
  30.         flags.push_back(tempb);
  31.         referenceNodes.push_back(tempn);
  32.         for (size_t x = 0; x < world->getMap()->tiles[y].size(); x++) {
  33.             flags[y].push_back(false);
  34.             referenceNodes[y].push_back(Node(x,y,0));
  35.         }
  36.     }
  37.     //Flag start position as explored, dont add to que.
  38.     flags[startpos.y][startpos.x] = true;
  39.  
  40.     //Debugger::print("initialized node checkpoints:" + toString(nodes[0].checkpoints.size()) + "\n");
  41.     nodes = findUnexploredSurroundingPaths(Vector2(x,y)); //Start out with the nodes around the start position;
  42.     for (int i = 0; i < nodes.size(); i++) {//Flag initial nodes
  43.         Debugger::print("Flagging:" + toString(nodes[i].pos.x) + ";" + toString(nodes[i].pos.y) + "  ");
  44.         flags[nodes[i].pos.y][nodes[i].pos.x] = true;
  45.         if (nodes[i].pos.x == (int)destinationPos.x && nodes[i].pos.y == (int)destinationPos.y) { //If one is the destination, return as vector
  46.             Debugger::print("\nDestination was adjacent\n");
  47.             vector<Node> n;
  48.             n.push_back(nodes[i]);
  49.             return Path(n);
  50.         }
  51.     }
  52.     Debugger::print("\n");
  53.  
  54.     int counter = 0;
  55.     while (nodes.size() > 0 && counter < 10000) { //while there are still more frontiers to explore
  56.         Node current = findShortestNode(nodes, true); //Select the shortest frontier
  57.         Debugger::print("Current:" + toString(current.pos.x) + "," + toString(current.pos.y) + "   Goal:" + toString((int)destinationPos.x) + "," + toString((int)destinationPos.y) + "\n");
  58.         //Debugger::print("Current node has size: " + toString(current.size) + " and position: " + toString(current.pos.x) + "," + toString(current.pos.y) + " and length " + toString(current.checkpoints.size()) + "\n");
  59.         vector<Node> next = findUnexploredSurroundingPaths(current.pos); //Find best direction to advance
  60.         for (int i = 0; i < next.size(); i++) {
  61.             Debugger::print("Next" + toString(i) + ":" + toString(next[i].pos.x) + "," + toString(next[i].pos.y) + " ");
  62.             //Manage the reference node
  63.             Node * refCur = &referenceNodes[(size_t)current.pos.y][(size_t)current.pos.x];
  64.             Node * refNext = &referenceNodes[(size_t)next[i].pos.y][(size_t)next[i].pos.x];
  65.             //Set where it was explored from
  66.             refNext->previousNode = refCur;
  67.             //Set total size
  68.             refNext->size = world->getMap()->getTravelWeightAt(refNext->pos.x, refNext->pos.y) + refCur->size;
  69.             //Create node on frontier
  70.             nodes.push_back(refNext->clone());
  71.             //Flag the position as explored
  72.             flags[next[i].pos.y][next[i].pos.x] = true;
  73.  
  74.             //Debugger::print("Returned node has size: " + toString(next.size) + " and position: " + toString(next.pos.x) + "," + toString(next.pos.y) + " and length " + toString(next.checkpoints.size()) + "\n");
  75.             //Debugger::print("Checkpoints are: ");
  76.             //for (int i = 0; i < next.checkpoints.size(); i++) {
  77.             //  Debugger::print(toString(next.checkpoints[i].pos.x) + "," + toString(next.checkpoints[i].pos.y) + " ");
  78.             //}
  79.             //Debugger::print("\n");
  80.  
  81.             //If the explored node is the goal
  82.             if (next[i].pos.x == (int)destinationPos.x && next[i].pos.y == (int)destinationPos.y) {
  83.                 //create a vector containing the explored path
  84.                 int i = 1;
  85.                 vector<Node> path;
  86.                 path.insert(path.begin(), *refNext);
  87.                 do {
  88.                     Debugger::print("Bulding path: " + toString(i) + "\n");
  89.                     refNext = refNext->previousNode; //If the path before that node does not have a path, stop
  90.                     path.insert(path.begin(), *refNext); //Insert current node
  91.                     i++;
  92.                 } while (refNext->previousNode != NULL);
  93.                 //return the path
  94.                 Debugger::print("\nFound path: " + toString(path.size()) + "\n");
  95.                 Debugger::print("\n");
  96.                 Debugger::print("\n");
  97.                 Debugger::print("\n");
  98.                 Debugger::print("\n");
  99.                 return Path(path);
  100.             }
  101.             //Create reference node
  102.         }
  103.         Debugger::print("\n");
  104.         //Node now explored, erase
  105.         Debugger::print("Position to be erased: " + toString(cIndex) + " contains:" + toString(nodes[cIndex].pos.x) + "," + toString(nodes[cIndex].pos.y) + "\n");
  106.         nodes.erase(nodes.begin() + cIndex);
  107.         //Go to new frontier
  108.        
  109.         //counter++;
  110.         for (int i = 0; i < flags.size(); i++) {
  111.             for (int j = 0; j < flags[i].size(); j++) {
  112.                 Debugger::print(toString(flags[i][j]));
  113.             }
  114.             Debugger::print("\n");
  115.         }
  116.         Debugger::print("\n");
  117.     }
  118.  
  119.     //If there is no path
  120.     Debugger::print("No path... Frontier size: "+ toString(nodes.size()) + "\n");
  121.  
  122.     Debugger::print("\n");
  123.     Debugger::print("\n");
  124.     Debugger::print("\n");
  125.     Debugger::print("\n");
  126.     vector<Node> start;
  127.     start.push_back(Node(startpos.x, startpos.y, 0));
  128.     return Path(start);
  129.    
  130. }
  131.  
  132. Node Navigator::findShortestNode(vector<Node> nodes, bool frontierNodes) {
  133.     //Look through all nodes and return the smallest. If it is the frontier node list, also note cIndex, to mark it for erasion if empty frontier
  134.     //(When searching for 'current')
  135.     //Compare to first
  136.     Node smallestN = nodes[0];
  137.     if(frontierNodes) cIndex = 0;
  138.     for (size_t i = 1; i < nodes.size(); i++) {//for each other element in frontier
  139.         if (nodes[i].size < smallestN.size) { //If size is smaller, set as prefered
  140.             smallestN = nodes[i];
  141.             if (frontierNodes) cIndex = i;
  142.         }
  143.     }
  144.     return smallestN;
  145. }
  146. vector<Node> Navigator::findUnexploredSurroundingPaths(Vector2 pos) {
  147.     //Find the surrounding paths, that are not flagged as explored
  148.     vector<Node> steps;
  149.     if (pos.x - 1 >= 0 //index x cant be below zero
  150.         && !flags[pos.y][pos.x - 1]) { //Flag must be false
  151.         steps.push_back(Node((int)(pos.x - 1), (int)pos.y, world->getMap()->getTravelWeightAt((int)(pos.x - 1), (int)pos.y))); //Add node with position and step weight
  152.     }
  153.     if (pos.x + 1 < flags[pos.y].size() //Index x cant be above the size of the y array at pos
  154.         && !flags[pos.y][pos.x + 1]) { //Flag must be false
  155.         steps.push_back(Node((int)(pos.x + 1), (int)pos.y, world->getMap()->getTravelWeightAt((int)(pos.x + 1), (int)pos.y))); //Add node with position and step weight
  156.     }
  157.     if (pos.y - 1 >= 0 && pos.x < flags[pos.y - 1].size() //Index y cant be above 0, and index cant be above the size of the y array at pos
  158.         && !flags[pos.y - 1][pos.x]) { //Flag must be false
  159.         steps.push_back(Node((int)pos.x, (int)(pos.y - 1), world->getMap()->getTravelWeightAt((int)pos.x, (int)(pos.y - 1)))); //Add node with position and step weight
  160.     }
  161.     if (pos.y + 1 < flags.size() && pos.x < flags[pos.y + 1].size() //Pos y must be below the amount of y's and index x cant be above the size of the y array at pos
  162.         && !flags[pos.y + 1][pos.x]) { //Flag must be false
  163.         steps.push_back(Node((int)pos.x, (int)(pos.y + 1), world->getMap()->getTravelWeightAt((int)pos.x, (int)(pos.y + 1)))); //Add node with position and step weight
  164.     }
  165.     return steps;
  166. }
  167. Node Navigator::findShortestSurroundingPaths(Node n) {
  168.     //find unexplored surrounding paths
  169.     vector<Node> surroundingPaths = findUnexploredSurroundingPaths(n.pos);
  170.  
  171.     //Find the shortest of them
  172.     Node shortest = findShortestNode(surroundingPaths);
  173.     //Debugger::print("Shortest path has size: " + toString((int)(shortest.size)) + "\n");
  174.     return shortest;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement