Advertisement
Guest User

A* Algorithm

a guest
Sep 27th, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.60 KB | None | 0 0
  1. //need struct for linked list node, list_node
  2. struct list_node{
  3.     list_node *next; //next in list, in whatever linked list it's in
  4.     list_node *prev; //previous in list, whatver linked list it's in
  5.     list_node *parent; //the parent (in regards to A* algo)
  6.     int x,y;
  7.     int f,g,h;
  8.     list_node(){
  9.         next = 0;
  10.         prev = 0;
  11.         parent = 0;
  12.         x,y,f,g,h = 0;
  13.     }
  14.     list_node(list_node* i_next, list_node* i_prev, list_node* i_parent, int i_x, int i_y, int i_f, int i_g , int i_h){
  15.         next = i_next;
  16.         prev = i_prev;
  17.         parent = i_parent;
  18.         x = i_x;
  19.         y = i_y;
  20.         f = i_f;
  21.         g = i_g;
  22.         h = i_h;
  23.     }
  24. };
  25.  
  26. //generic struct for linked lists
  27. struct list{
  28.     list_node* first;
  29.     list_node* last;
  30. };
  31.  
  32. //An even better A*, gash damn!
  33. vector<vector<int>> A_star(bool block_map[],int map_width, int x1, int y1, int x2, int y2){
  34.     vector<vector<int>> search_q; //the main "list", could really be turned into what ever datat type you wantx
  35.    
  36.     list open_set = {nullptr,nullptr}; //the start of the open_set
  37.     list closed_set = {nullptr,nullptr};; //the start of the closed_set
  38.    
  39.     //create first node
  40.     list_node temp = {nullptr, nullptr, nullptr, x1, y1, 0, 0, 0};
  41.    
  42.     //add it to open_set
  43.     open_set.first = &temp;
  44.     open_set.last = &temp;
  45.    
  46.     //while open_set isn't empty, keep picking off the node with the smallest f
  47.     int it2debug = 0;
  48.     while(open_set.first!=nullptr){
  49.        
  50.         //find node in open_set with least f, make it q
  51.         ///////////////////////////////////
  52.         bool search_f = true;
  53.         list_node* lowest_f = nullptr; //points to the node with lowest f
  54.         int least_f = 999999; //start with high (lol) number
  55.         list_node* current = open_set.first; //points to the current node, we're searching
  56.         while(search_f){
  57.            
  58.             if(current == nullptr){
  59.                 break;
  60.             }
  61.            
  62.             if(current->f<=least_f){ //if, it'shas a lesser f, point to it... THIS ALSO ENSURES THE LAST ONE POPPED ON GETS PICKED
  63.                 lowest_f = current;
  64.                 least_f = lowest_f->f;
  65.             }
  66.             if(current==open_set.last){ //if cuurently pointing to last nodee, then stop search
  67.                 search_f = false;
  68.             }else{
  69.                 current = current->next;
  70.             }
  71.         }
  72.         //when done with search, lowest_f should point to node with lowest f
  73.        
  74.         //Find lowest_f node in open_set and call it q
  75.         ////////////////////////////
  76.         list_node* q = lowest_f; //q has the lowest f
  77.        
  78.         /////DEBUGGG AGAIN DAMNNN
  79.         if(it2debug>0){printf("\n Q: (%d,%d,%d,%d)",q->x, q->y, (q->parent)->x, (q->parent)->y);}
  80.         it2debug++;
  81.        
  82.         //POPping off q from OPEN_SET
  83.         ////////////////////////
  84.         if(q->prev!=nullptr){ //if lowest_f is not FIRST in list
  85.             (q->prev)->next = q->next; //update the previous node in list
  86.         }else{ //if lowest_f is first in list
  87.             open_set.first = q->next; //update the open_set struct
  88.         }
  89.         if(q->next!=nullptr){ //if lowest_f is not LAST in list
  90.             (q->next)->prev = q->prev; //update the next node in list
  91.         }else{ //if lowest_f is last in list
  92.             open_set.last = q->prev; //update the open_set struct
  93.         }
  94.         //open_set (and it's elements) are correct and up to date
  95.        
  96.         list_node* neighbors[4]; //The FOUR neighbors
  97.         neighbors[0] = new list_node;
  98.         *neighbors[0] = {nullptr, nullptr, q, (q->x)-1 , q->y , 9999, 9999, 9999};
  99.         neighbors[1] = new list_node;
  100.         *neighbors[1] = {nullptr, nullptr, q, (q->x)+1 , q->y , 9999, 9999, 9999};
  101.         neighbors[2] = new list_node;
  102.         *neighbors[2] = {nullptr, nullptr, q, q->x , (q->y)-1 , 9999, 9999, 9999};
  103.         neighbors[3] = new list_node;
  104.         *neighbors[3] = {nullptr, nullptr, q, q->x , (q->y)+1 , 9999, 9999, 9999};
  105.        
  106.         //For each neighbor/successor
  107.         for(int i = 0; i<4; i++){
  108.            
  109.             //if neighbor is target, then we can stop
  110.             if((neighbors[i]->x==x2)&&(neighbors[i]->y==y2)){
  111.                 printf("reach the kind and gentle trget");
  112.                 //Just so it terminates
  113.                 open_set.first=nullptr;
  114.                 open_set.last=nullptr;
  115.                 break;
  116.             }
  117.            
  118.             //if neighbor tile is blocked then we can stop
  119.             //neighbor[0]->
  120.             if(block_map[(neighbors[i]->y*map_width)+neighbors[i]->x]==true){
  121.                 continue; //move on to next neighbor
  122.             }
  123.            
  124.             //Calculate The 3 Values: f, g, h
  125.             neighbors[i]->g = q->g + 1;
  126.             neighbors[i]->h = abs(y2-(neighbors[i]->y)) + abs(x2-(neighbors[i]->x));
  127.             neighbors[i]->f = neighbors[i]->g + neighbors[i]->h;
  128.            
  129.             //Cycle Through OPEN_SET and check if the neighbor is already in there (with lower f or does it matter here?)
  130.             bool search_o = true; //search flag
  131.             bool in_open =  false; //flag indicating if neighbor is in OPNE_SET
  132.             current = open_set.first; //start at beginning
  133.             while(search_o){
  134.                
  135.                 //Check if at end of list
  136.                 if(current==nullptr){
  137.                     search_o = false;
  138.                     break;
  139.                 }
  140.                
  141.                 //Check x,y values in node
  142.                 if( (current->x==neighbors[i]->x) && (current->y==neighbors[i]->y)){
  143.                     in_open = true;
  144.                 }
  145.              
  146.                 //Move on to search next node in list
  147.                 current = current->next;
  148.                
  149.             }
  150.             if(in_open){
  151.                 continue; //skip this neighbor
  152.             }
  153.            
  154.             //Cycle Through CLOSED_SET and check if the neighbor is already in there (with lower f or does it matter here?)
  155.             bool search_c = true; //search flag
  156.             bool in_closed =  false; //flag indicating if neighbor is in CLOSED_SET
  157.             current = closed_set.first; //start at beginning
  158.             while(search_c){
  159.                
  160.                 //Check if at end of list
  161.                 if(current==nullptr){
  162.                     search_c = false;
  163.                     break;
  164.                 }
  165.                
  166.                 //Check x,y values in node
  167.                 if( (current->x==neighbors[i]->x) && (current->y==neighbors[i]->y)){
  168.                     in_closed = true;
  169.                 }
  170.                
  171.                 //Move on to search next node in list
  172.                 current = current->next;
  173.                
  174.             }
  175.             if(in_closed){
  176.                 continue; //skip this neighbor
  177.             }
  178.            
  179.             //If we've made it to this point, it isn't in CLOSED or OPEN SET
  180.             //ADD neighbor to OPEN_SET
  181.             neighbors[i]->next = nullptr; //indicate neighbor is at end of list
  182.             neighbors[i]->prev = open_set.last; //update neighbor who it's behind
  183.             if(open_set.last!=nullptr){open_set.last->next = neighbors[i];} //the (former) last item in list now points to neighbor
  184.             open_set.last = neighbors[i]; //the open_set is updated
  185.             if(open_set.first==nullptr){open_set.first= neighbors[i];}; //if this is the first item in open_set
  186.  
  187.            
  188.         }//Done cycling through neighbors
  189.        
  190.         //ADD q to CLOSED_SET
  191.         q->next = nullptr; //indicate q is at end of list
  192.         q->prev = closed_set.last; //update q who it's behind
  193.         if(closed_set.last!=nullptr){closed_set.last->next = q;} //the (former) last item in list now points to neighbor
  194.         closed_set.last= q; //the open_set is updated
  195.         if(closed_set.first==nullptr){closed_set.first= q;}; //if this is the first item in open_set
  196.        
  197.         //DEBUGGING
  198.         //Print out the closed and open_sets
  199.         //...the closed set
  200.         bool printing = true;
  201.         list_node* current2 = closed_set.first;
  202.         printf("\nCLOSED: ");
  203.         while(printing){
  204.             if(current2==nullptr){
  205.                 printing = false;
  206.                 break;
  207.             }
  208.             printf(" (%d,%d) ", current2->x, current2->y );
  209.             current2 = current2->next;
  210.            
  211.         }
  212.         //...the open set
  213.         printing = true;
  214.         current2 = open_set.first;
  215.         printf("\nOPEN: ");
  216.         while(printing){
  217.             if(current2==nullptr){
  218.                 printing = false;
  219.                 break;
  220.             }
  221.             if(current2==current2->next){current2->next = nullptr;}
  222.             printf(" (%d,%d,%d) ", current2->x, current2->y, current2->f );
  223.             current2 = current2->next;
  224.         }
  225.        
  226.        
  227.         //Just so it terminates
  228.         //open_set.first=nullptr;
  229.         //open_set.last=nullptr;
  230.        
  231.     }//end open_list empty
  232.    
  233.     //ADD final target onto CLOSED_SET
  234.     list_node* final_node = new list_node; //a temporary node for final step
  235.     *final_node = {nullptr, nullptr, closed_set.last, x2 , y2 , 9999, 9999, 9999};
  236.     final_node->next = nullptr; //indicate q is at end of list
  237.     final_node->prev = closed_set.last; //update q who it's behind
  238.     if(closed_set.last!=nullptr){closed_set.last->next = final_node;} //the (former) last item in list now points to neighbor
  239.     closed_set.last = final_node; //the open_set is updated
  240.     if(closed_set.first==nullptr){closed_set.first= final_node;}; //if this is the first item in open_set
  241.    
  242.     //DEBUGGING
  243.     //Print out the closed and open_sets
  244.     //...the closed set
  245.     bool printing = true;
  246.     list_node* current = closed_set.first;
  247.     printf("\nCLOSED: ");
  248.     while(printing){
  249.         if(current==nullptr){
  250.             printing = false;
  251.             break;
  252.         }
  253.         printf(" (%d,%d) ", current->x, current->y );
  254.         list_node* temp = current; //Fo deletion
  255.         current = current->next;
  256.         delete temp; //Also fo deletion
  257.        
  258.     }
  259.     //...the open set
  260.     printing = true;
  261.     current = open_set.first;
  262.     printf("\nOPEN: ");
  263.     while(printing){
  264.         if(current==nullptr){
  265.             printing = false;
  266.             break;
  267.         }
  268.         printf(" (%d,%d,%d) ", current->x, current->y, current->f );
  269.         list_node* temp; //fo deletion
  270.         current = current->next;
  271.         delete temp; //also fo deletion
  272.        
  273.     }
  274.    
  275.    
  276.     printf("one day on eddsa");
  277.     return search_q;
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement