libtcoddocumentation

16.1. Creating a path

Allocating a pathfinder from a map

First, you have to allocate a path using a map from the Field of view module.

TCODPath::TCODPath(const TCODMap *map, float diagonalCost=1.41f)
TCODDijkstra::TCODDijkstra(const TCODMap *map, float diagonalCost=1.41f)

TCOD_path_t TCOD_path_new_using_map(TCOD_map_t map, float diagonalCost)
TCOD_dijkstra_t
TCOD_dijkstra_new(TCOD_map_t map, float diagonalCost)

path_new_using_map(map, diagonalCost=1.41)
dijkstra_new(map, diagonalCost=1.41)

Parameter Description
map The map. The path finder will use the 'walkable' property of the cells to find a path.
diagonalCost Cost of a diagonal movement compared to an horizontal or vertical movement. On a standard cartesian map, it should be sqrt(2) (1.41f).
It you want the same cost for all movements, use 1.0f.
If you don't want the path finder to use diagonal movements, use 0.0f.
Example:

// A* :
TCODMap *myMap = new TCODMap(50,50);
TCODPath *path = new TCODPath(myMap); // allocate the path
// Dijkstra:
TCODMap *myMap = new TCODMap(50,50);
TCODDijkstra *dijkstra = new TCODDijkstra(myMap);

// A* :
TCOD_map_t my_map=TCOD_map_new(50,50,true);
TCOD_path_t
path = TCOD_path_new_using_map(my_map,1.41f);
// Dijkstra :
TCOD_map_t my_map=TCOD_map_new(50,50,true);
TCOD_dijkstra_t
dijk = TCOD_dijkstra_new(my_map,1.41f);

# A* :
my_map=libtcod.map_new(50,50,True)
path = libtcod.path_new_using_map(my_map)
# Dijkstra
my_map=libtcod.map_new(50,50,True)
dijk = libtcod.dijkstra_new(my_map)


Allocating a pathfinder using a callback

Since the walkable status of a cell may depend on a lot of parameters (the creature type, the weather, the terrain type...), you can also create a path by providing a function rather than relying on a TCODMap.

// Callback :
class ITCODPathCallback {
    public
: virtual float getWalkCost( int xFrom, int yFrom, int xTo, int yTo, void *userData ) const = 0;
}
;
// A* constructor:
TCODPath::TCODPath(int width, int height, const ITCODPathCallback *callback, void *userData, float diagonalCost=1.41f)
// Dijkstra constructor
TCODDijkstra::TCODDijkstra(int width, int height, const ITCODPathCallback *callback, void *userData, float diagonalCost=1.41f)

typedef float (*TCOD_path_func_t)( int xFrom, int yFrom, int xTo, int yTo, void *user_data )
TCOD_path_t
TCOD_path_new_using_function(int width, int height, TCOD_path_func_t callback, void *user_data, float diagonalCost)
TCOD_dijkstra_t
TCOD_dijkstra_new_using_function(int width, int height, TCOD_path_func_t callback, void *user_data, float diagonalCost)

def path_func(xFrom,yFrom,xTo,yTo,userData) : ...
path_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41)
dijkstra_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41)

Parameter Description
width,height The size of the map (in map cells).
callback A custom function that must return the walk cost from coordinates xFrom,yFrom to coordinates xTo,yTo.
The cost must be > 0.0f if the cell xTo,yTo is walkable.
It must be equal to 0.0f if it's not.
You must not take additional cost due to diagonal movements into account as it's already done by the pathfinder.
userData Custom data that will be passed to the function.
diagonalCost Cost of a diagonal movement compared to an horizontal or vertical movement. On a standard cartesian map, it should be sqrt(2) (1.41f).
It you want the same cost for all movements, use 1.0f.
If you don't want the path finder to use diagonal movements, use 0.0f.
Example:

class MyCallback : public ITCODPathCallback {
public
:
    float
getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const { ... }
}
;
TCODPath *path = new TCODPath(50,50,new MyCallback(),NULL); // allocate the path
TCODDijkstra *dijkstra = new TCODDijkstra(50,50,new MyCallback(),NULL);

float my_func(int xFrom, int yFrom, int xTo, int yTo, void *user_data) { ... }
TCOD_path_t
path = TCOD_path_new_using_function(50,50,my_func,NULL,1.41f);
TCOD_dijkstra_t
dijkstra = TCOD_dijkstra_new_using_function(50,50,my_func,NULL,1.41f);

def my_func(xFrom, yFrom, xTo, yTo, user_data) :
    # return a float cost for this movement
    
return 1.0
path = libtcod.path_new_using_function(50,50,my_func)
dijkstra = libtcod.dijkstra_new_using_function(50,50,my_func)


Destroying a path

To release the resources used by a path, destroy it with :

TCODPath::~TCODPath()
TCODDijkstra::~TCODDijkstra()

void TCOD_path_delete(TCOD_path_t path)
void
TCOD_dijkstra_delete(TCOD_dijkstra_t dijkstra)

path_delete(path)
dijkstra_delete(dijkstra)

Parameter Description
path In the C version, the path handler returned by one of the TCOD_path_new_* function.
dijkstra In the C version, the path handler returned by one of the TCOD_dijkstra_new* function.
Example:

TCODPath *path = new TCODPath(myMap); // allocate the path
// use the path...
delete path; // destroy the path
    
TCODDijkstra *dijkstra = new TCODDijkstra(myMap); // allocate the path
// use the path...
delete dijkstra;

TCOD_path_t path = TCOD_path_new_using_map(my_map);
// use the path ...
TCOD_path_delete(path);
    TCOD_dijkstra_t
dijkstra = TCOD_dijkstra_new(my_map);
// use the path ...
TCOD_dijkstra_delete(dijkstra);

path = libtcod.path_new_using_map(my_map)
# use the path ...
libtcod.path_delete(path)
    dijkstra = libtcod.dijkstra_new(my_map)
# use the path ...
libtcod.dijkstra_delete(dijkstra)