示例#1
0
Point _get_aiPath(const FathomData* fathom, Point start, Point end)
{
  Point move = NULL_POINT;
  _aStarFathom = fathom;
  _aStarStartPoint = start;
  _aStarFinishPoint = end;
  astar_t *as = astar_new(TILEMAP_WIDTH, TILEMAP_HEIGHT, _get_map_cost, NULL);
  astar_set_origin (as, 0, 0);
  astar_set_steering_penalty (as, 0);
  astar_set_movement_mode (as, DIR_CARDINAL);
  astar_run (as, start.x, start.y, end.x, end.y);
  if(astar_have_route(as))
  {
    direction_t * directions, * dir;
    astar_get_directions (as, &directions);    
    dir = directions;
    move.x += astar_get_dx(as, *dir);
    move.y += astar_get_dy(as, *dir);
    astar_free_directions (directions);
  }
  return move;
}
示例#2
0
int astar_test_main()
{
	astar_t * as;
	int x0, y0, x1, y1;
	int result;

	srand(time(NULL));

	// Initialise the map.
	map_init();

	// Allocate an A* context.
	as = astar_new (WIDTH, HEIGHT, get_map_cost, NULL);

	// Set the map origin. This allows us to look for a route in
	// an area smaller than the full game map (by setting the
	// origin to the origin of that area, and giving astar_new() a
	// width and height smaller than the full map's. It's
	// mandatory to set this, even if it's just zero. If you don't set it,
	// the algorithm will fail with an ASTAR_ORIGIN_NOT_SET error.

	astar_set_origin (as, 0, 0);

	// By setting the steering penalty, you penalise direction
	// changes. This can lead in more direct routes, but it can also make
	// the algorithm work harder to find a route. The default pre-bundled
	// value for this cost is 5 (5 less than the cost of moving in the four
	// cardinal directions). Set it to zero, and the route can meander
	// more.

	// astar_set_steering_penalty (as, 5);

	// If you have a preference for movement in the cardinal directions
	// only, assign a high cost to the other four directions. If the only
	// way to get from A to B is to move dianogally, a diagonal move will
	// still be used though.

	// astar_set_cost (as, DIR_NE, 100);
	// astar_set_cost (as, DIR_NW, 100);
	// astar_set_cost (as, DIR_SW, 100);
	// astar_set_cost (as, DIR_SE, 100);

	// Instead, if you want to only route using the four cardinal
	// directions, say this:

	// astar_set_movement_mode (as, DIR_CARDINAL);
	// astar_set_movement_mode (as, DIR_8WAY); // This is the default.

	// Starting near the upper left corner of the map.
	x0 = 2;
	y0 = 1;

	// Destination near the lower right corner.
	x1 = WIDTH - 3;
	y1 = HEIGHT - 1;

	// Look for a route.
	result = astar_run (as, x0, y0, x1, y1);

	// What's the result?
	printf ("Route from (%d, %d) to (%d, %d). Result: %s (%d)\n",
		as->x0, as->y0,
		as->x1, as->y1,
		as->str_result, result);

	// Do we have a route? We don't care if the route is partial
	// or full here. If you need a full route, you must ensure the return
	// value of astar_run is ASTAR_FOUND. If it isn't, and
	// astar_have_route() returns non-zero, there's a (possibly partial)
	// route.

	if (astar_have_route (as)) {
		direction_t * directions, * dir;
		uint32_t i, num_steps;
		int x, y;

		num_steps = astar_get_directions (as, &directions);

		if (result == ASTAR_FOUND) {
			printf ("We have a route. It has %d step(s).\n", num_steps);
		} else {
			printf ("The best compromise route has %d step(s).\n", num_steps);
		}

		// The directions start at our (x0, y0) and give us
		// step-by-step directions (e.g. N, E, NE, N) to
		// either our (x1, y1) in the case of a full route, or
		// the best compromise.
		x = x0;
		y = y0;
		dir = directions;
		for (i = 0; i < num_steps; i++, dir++) {

			// Convince ourselves that A* never made us go through walls.
			assert (get_map (x, y) != MAP_WALL);

			// Mark the route on the map.
			set_map (x, y, MAP_ROUTE);

			// Get the next (x, y) co-ordinates of the map.
			x += astar_get_dx (as, *dir);
			y += astar_get_dy (as, *dir);
		}

		// Mark the starting and ending squares on the map. Do this last.
		set_map (x0, y0, MAP_START);
		set_map (x1, y1, MAP_END);

		// VERY IMPORTANT: MEMORY LEAKS OTHERWISE!
		astar_free_directions (directions);
	}

	// Print the map.
	map_print();

	// Dellocate the A* algorithm context.
	astar_destroy (as);
        return 0;
}