示例#1
0
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;
}
示例#2
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, &currentTile, &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);
    }
}
示例#3
0
// 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;
}
示例#4
0
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;
}
示例#5
0
/* 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;

}