char *test_astar() { ASPathNodeSource graph = { sizeof(int), &t_buildNeighbors, &t_heuristic, NULL, NULL }; int from = 0; int to = 2; ASPath path = ASPathCreate(&graph, NULL, &from, &to); mu_assert("astar: cost from 0 to 2 is not correct", equal(ASPathGetCost(path), 2)); ASPathDestroy(path); to = 5; path = ASPathCreate(&graph, NULL, &from, &to); mu_assert("astar: cost from 0 to 5 is not correct", equal(ASPathGetCost(path), 5)); ASPathDestroy(path); return 0; }
int AIGoto(TActor *actor, Vec2i p, bool ignoreObjects) { Vec2i a = Vec2iFull2Real(actor->Pos); Vec2i currentTile = Vec2iToTile(a); Vec2i goalTile = Vec2iToTile(p); AIGotoContext *c = &actor->aiContext->Goto; // If we are already there, bail // This can happen if AI is trying to track the player, // but the player has died, for example. if (Vec2iEqual(currentTile, goalTile)) { return 0; } // If we are currently following an A* path, // and it is still valid, keep following it until // we have reached a new tile if (c && c->IsFollowing && AStarCloseToPath(c, currentTile, goalTile)) { return AStarFollow(c, currentTile, &actor->tileItem, a); } else if (AIHasClearPath(a, p, ignoreObjects)) { // Simple case: if there's a clear line between AI and target, // walk straight towards it return AIGotoDirect(a, p); } else { // We need to recalculate A* AStarContext ac; ac.Map = &gMap; ac.IsTileOk = ignoreObjects ? IsTileWalkable : IsTileWalkableAroundObjects; // First, if the goal tile is blocked itself, // find a nearby tile that can be walked to c->Goal = MapSearchTileAround(ac.Map, goalTile, ac.IsTileOk); c->PathIndex = 1; // start navigating to the next path node ASPathDestroy(c->Path); c->Path = ASPathCreate( &cPathNodeSource, &ac, ¤tTile, &c->Goal); // In case we can't calculate A* for some reason, // try simple navigation again if (ASPathGetCount(c->Path) <= 1) { debug( D_MAX, "Error: can't calculate path from {%d, %d} to {%d, %d}", currentTile.x, currentTile.y, goalTile.x, goalTile.y); return AIGotoDirect(a, p); } return AStarFollow(c, currentTile, &actor->tileItem, a); } }
// Use pathfinding to check that there is a path between // source and destination tiles bool AIHasPath(const Vec2i from, const Vec2i to, const bool ignoreObjects) { // Quick first test: check there is a clear path if (AIHasClearPath(from, to, ignoreObjects)) { return true; } // Pathfind AStarContext ac; ac.Map = &gMap; ac.IsTileOk = ignoreObjects ? IsTileWalkable : IsTileWalkableAroundObjects; Vec2i fromTile = Vec2iToTile(from); Vec2i toTile = MapSearchTileAround(ac.Map, Vec2iToTile(to), ac.IsTileOk); ASPath path = ASPathCreate(&cPathNodeSource, &ac, &fromTile, &toTile); size_t pathCount = ASPathGetCount(path); ASPathDestroy(path); return pathCount > 1; }
double stFunc(TraceNode *p1, TraceNode *p2, Candidate *c1, Candidate *c2, NodeSet *searched) { double s; double t; ASPathNodeSource graph = { sizeof(Node), &buildNeighbors, &heuristic, NULL, NULL }; ASPath path = ASPathCreate(&graph, searched, c1->prevNode, c2->nextNode); if(path == NULL) { return -10000; } s = spatialFunc(&p1->data, &p2->data, c1, c2, path); t = temporalFunc(path, p1, p2); ASPathDestroy(path); return s * t; }
/* This test it to test my function getEdges, which is to extract edges * from the 3rd party astar algorithm result */ char *test_astar_getedges() { ASPathNodeSource graph = { sizeof(Node), &buildNeighbors, &heuristic, NULL, NULL }; NodeSet set; Node n0; Node n1; Node n2; Node n3; Node n4; Node *noderefs[5] = {&n0, &n1, &n2, &n3, &n4}; Edge e0; Edge e1; Edge e2; Edge e3; Edge e4; Edge e5; Edge *oel0[2] = {&e0, &e1}; Edge *oel1[2] = {&e4, &e5}; Edge *oel2[1] = {&e2}; Edge *oel3[1] = {&e3}; Edge *oel4[1]; Edge *iel0[1]; Edge *iel1[1] = {&e0}; Edge *iel2[2] = {&e1, &e5}; Edge *iel3[1] = {&e4}; Edge *iel4[2] = {&e2, &e3}; ASPath path; n0.id = 0; n1.id = 1; n2.id = 2; n3.id = 3; n4.id = 4; n0.outdegree = 2; n1.outdegree = 2; n2.outdegree = 1; n3.outdegree = 1; n4.outdegree = 0; n0.indegree = 0; n1.indegree = 1; n2.indegree = 2; n3.indegree = 1; n4.indegree = 2; n0.outedges = oel0; n1.outedges = oel1; n2.outedges = oel2; n3.outedges = oel3; n4.outedges = oel4; n0.inedges = iel0; n1.inedges = iel1; n2.inedges = iel2; n3.inedges = iel3; n4.inedges = iel4; e0.id = 0; e1.id = 1; e2.id = 2; e3.id = 3; e4.id = 4; e5.id = 5; e0.length = 1; e1.length = 2; e2.length = 2; e3.length = 1; e4.length = 1; e5.length = 2; e0.head = &n0; e1.head = &n0; e2.head = &n2; e3.head = &n3; e4.head = &n1; e5.head = &n1; e0.tail = &n1; e1.tail = &n2; e2.tail = &n4; e3.tail = &n4; e4.tail = &n3; e5.tail = &n2; set.count = 5; set.refs = noderefs; path = ASPathCreate(&graph, &set, &n0, &n4); mu_assert("astar get edges: count incorrect ", getEdgeCount(path) == 3); mu_assert("astar get edges: total length incorrect", equal(ASPathGetCost(path), 3)); mu_assert("astar get edges: 3 incorrect ", getEdges(path)[2]->id == 3); path = ASPathCreate(&graph, &set, &n4, &n0); printf("%lf", ASPathGetCost(path)); ASPathDestroy(path); return 0; }