//this is the path finding portion of the program. #include "../common/types.h" #include "../zone/map.h" #include "../common/rdtsc.h" #include "quadtree.h" #include "apathing.h" #include "boostcrap.h" #include #include #include #include #include #include #include #include using namespace std; void find_path_info(Map *map, PathGraph *big, vector< vector > &path_finding) { //make sure our path finding vector is big enough, and all NULL { int size = big->nodes.size(); vector tmp(size, (PathEdge*)NULL); path_finding.resize(0); path_finding.resize(size, tmp); } //take our minimal spanning tree and try to link every single //point in it like spawns are linked. The idea is to create //a large set of alternative paths and cycles. //get our list of nodes. list all_points = big->nodes; big->nodes.clear(); //make our current edge list std::map< pair, bool > edgelist; list::iterator cure,ende,tmp; PathEdge *e; cure = big->edges.begin(); ende = big->edges.end(); PathNode *from; PathNode *to; for(; cure != ende; cure++) { e = *cure; from = e->from; to = e->to; //hack to make order on the ID not matter if(int32(from) < int32(to)) { PathNode *tmp = from; from = to; to = tmp; } pair id(from, to); edgelist[id] = true; } //link up the points, making sure not to add edges allready in the MST link_spawns(map, big, all_points, FINAL_LINK_POINTS_DIST, &edgelist); //now we have our graph all connected up. /* disabled in favor of all-pairs shortest path. //get the list of edges leaving each node. std::map > node_edges; find_node_edges(big, node_edges); //color every node 0 list::iterator curn, endn; curn = big->nodes.begin(); endn = big->nodes.end(); for(; curn != endn; curn++) { (*curn)->color = 0; } //for each node, run a breadth first search from each node to find the //shortest path to each node from each node. */ //run all pairs shortest path so we have some information to //use for our metric in A* //build our boost graph with length weights MyGraph vg(big->nodes.size()); property_map::type weightlist; std::map edgemap; build_boost_graph(vg, weightlist, edgemap, big, true); //set weights to distances vector< vector > D; vector counts; vector disjoint_counts; vector first_node; //color the graph and get us the info we need to do our job (D) color_disjoint_graphs(big, vg, map, NULL, D, counts, disjoint_counts, first_node); //figure out what edges link to each node. std::map > node_edges; find_node_edges(big, node_edges); int cur_node_id; list::iterator curn,endn; PathNode *n; vector::iterator curp,endp; vector::iterator curev,endev; vector::iterator cur_res, end_res; curn = big->nodes.begin(); endn = big->nodes.end(); for(; curn != endn; curn++) { n = *curn; //get all our vector refs that we need since vector &cv = D[n->node_id]; //distance array vector &pf = path_finding[n->node_id]; //result vector &el = node_edges[n]; //our edges //for each other node, find an edge which gets us closer to that node curp = cv.begin(); endp = cv.end(); cur_res = pf.begin(); end_res = pf.end(); for(cur_node_id = 0; curp != endp && cur_res != end_res; curp++, cur_node_id++, cur_res++) { int distance_to_cur_node = *curp; //if this ourself, we have no path basically. if(n->node_id == cur_node_id) { *cur_res = NULL; continue; } //if we cant reach them, why look if(distance_to_cur_node == INT_MAX) { *cur_res = NULL; continue; } //see which edge gets us closer int closest = distance_to_cur_node; //start with the distance between this node and the target node, we need something closer PathEdge *best_edge = NULL; curev = el.begin(); endev = el.end(); for(; curev != endev; curev++) { e = *curev; int this_dist; //distance from the other end of this edge to the current target node if(e->from == n) { if(e->to->node_id == cur_node_id) this_dist = 0; //this is the goal node else this_dist = D[e->to->node_id][cur_node_id]; } else { //assume e->to == n if(e->from->node_id == cur_node_id) this_dist = 0; //this is the goal node else this_dist = D[e->from->node_id][cur_node_id]; } if(this_dist == 0) { //this will be the best. best_edge = e; break; } if(this_dist == INT_MAX) continue; //not reachable if(this_dist < closest) { closest = this_dist; best_edge = e; } } if(best_edge == NULL) { //unable to find a path... printf("Should have been able to find a path from %d to %d, but couldent.\n", n->node_id, cur_node_id); } *cur_res = best_edge; } } /* we have our node edges, our all pairs shortest path our graphs, and our MST edge list. now we can run A* - our metric should use the all pairs shortest path to determine the value for h. - We want to favor edges from the MST over newly created edges, so we will give such edges a lower weight, maybe by 20%? */ }