liblashgame

Pathfinder and path decision making library for 2D tile game
git clone git://holbrook.no/liblashgame.git
Log | Files | Refs

lash_game_map_wrapper.c (8267B)


      1 #include <stdio.h>
      2 #include <stdlib.h>  
      3 
      4 #include "Python.h"
      5 
      6 #include "liblashgame/lash_game_map.h"
      7 #include "liblashgame/lash_game_path_simple.h"
      8 
      9 void mapDestroy(PyObject *capsule) {
     10 	
     11 	lash_map_simple_t *map; 
     12 
     13 	//fprintf(stderr, "Entered destructor\n");
     14 
     15 	map = (lash_map_simple_t*)PyCapsule_GetPointer(capsule, "MAP_C_API");
     16 	if (map == NULL)
     17 		 return;
     18 		 
     19 	//fprintf(stderr, "Destroying map %p\n", map);
     20 	
     21 	lash_mapSimpleFree(map);  
     22 	free(map);
     23 	
     24 }   
     25   
     26 static PyObject * mapSimpleInit_func(PyObject *self, PyObject *args) {
     27 	unsigned int w;
     28 	unsigned int h;
     29 	PyObject *pymap;
     30 	
     31 	lash_map_simple_t *map = (lash_map_simple_t*)malloc(sizeof(lash_map_simple_t));
     32 	
     33 	if (!PyArg_ParseTuple(args, "II", &w, &h)) {
     34 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
     35 		return NULL;
     36 	}
     37 	
     38 	if (!lash_mapSimpleInit(map, &w, &h)) {
     39 		PyErr_SetString(PyExc_RuntimeError, "Cannot initialize map!  ");
     40 		return NULL;
     41 	}
     42 	
     43 	
     44 	pymap = PyCapsule_New((void *)map, "MAP_C_API", mapDestroy);
     45 	
     46  //	free(map);
     47 	
     48 	return Py_BuildValue("O", pymap);
     49 	  
     50 } 
     51 
     52 static PyObject * mapSimplePeek_func(PyObject *self, PyObject *args) {
     53 	lash_game_map_index_t idx;
     54 	lash_map_simple_t *map;
     55 	PyObject *pymap;
     56 	
     57 	if (!PyArg_ParseTuple(args, "Ok", &pymap, &idx)) {
     58 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
     59 		return NULL;
     60 	}
     61 	
     62 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
     63 	
     64 	if (idx >= *(map->w) * *(map->h))
     65 		return NULL; 
     66 		 
     67 	return Py_BuildValue("h", (unsigned short)lash_mapSimpleLayerPeek(map->layer_path, idx));
     68 }
     69 
     70 static PyObject * mapSimplePoke_func(PyObject *self, PyObject *args) {
     71 	lash_game_map_index_t idx;
     72 	unsigned short val;
     73 	lash_map_simple_t *map;
     74 	PyObject *pymap;
     75 	
     76 	if (!PyArg_ParseTuple(args, "Okh", &pymap, &idx, &val)) {
     77 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
     78 		return NULL;
     79 	}
     80 	
     81 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
     82 	
     83 	if (idx < *(map->w) * *(map->h))
     84 		lash_mapSimpleLayerPoke(map->layer_path, idx, (lash_map_simple_layer_item_t)val);
     85 	
     86 	return Py_BuildValue("s", NULL);
     87 }
     88 
     89 static PyObject * getMapSizeUnits_func(PyObject *self, PyObject *args) {
     90 	
     91 	lash_map_simple_t *map;
     92 	PyObject *pymap;
     93 	
     94 	if (!PyArg_ParseTuple(args, "O", &pymap)) 
     95 		return NULL;
     96 	
     97 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
     98 	if (map == NULL) {
     99 		PyErr_SetString(PyExc_RuntimeError, "Invalid map object");
    100 		return NULL;
    101 	}
    102 	
    103 	return Py_BuildValue("II", *(map->w), *(map->h));
    104 	
    105 }
    106  
    107 static PyObject * getPathFreeSpaces_func(PyObject *self, PyObject *args) {
    108 	int i;
    109 	
    110 	lash_map_simple_t *map;
    111 	
    112 	// args
    113 	PyObject *pymap;
    114 	
    115 	// process
    116 	unsigned int mapsize;
    117 	
    118 	// result
    119 	unsigned int *freeindices;
    120 	int freeindices_count;
    121 	PyObject *freeindices_final;
    122 	
    123 	if (!PyArg_ParseTuple(args, "O", &pymap)) {
    124 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
    125 		return NULL;
    126 	}
    127 	
    128 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
    129 	if (map == NULL) {
    130 		PyErr_SetString(PyExc_RuntimeError, "Invalid map object");
    131 		return NULL;
    132 	}
    133 	
    134 	mapsize = lash_mapSimpleGetSize(map);
    135 	
    136 	freeindices = (unsigned int*)calloc(sizeof(unsigned int), mapsize);
    137 	if (freeindices == NULL) {
    138 		PyErr_SetString(PyExc_RuntimeError, "Could not allocate array to hold free spaces index list");
    139 		return NULL;
    140 	}
    141 		
    142 	freeindices_count = lash_pathSimpleCompileFreeSpaces(&freeindices, mapsize, map->layer_path, mapsize, NULL, 0);
    143 	 
    144 	if (freeindices_count == -1) {
    145 		PyErr_SetString(PyExc_RuntimeError, "List compilation of free spaces failed");
    146 		return NULL;
    147 	}
    148 	
    149 	freeindices_final = PyList_New(freeindices_count);
    150 	
    151 	for (i = 0; i < freeindices_count; i++) {
    152 		PyObject *newindex = Py_BuildValue("I", (unsigned int)*(freeindices + i));
    153 		//if (PyList_SetItem(freeindices_final, i, PyBytes_FromFormat("%u", (unsigned int)*(freeindices + i))) == -1) {
    154 		if (PyList_SetItem(freeindices_final, i, newindex) == -1) {
    155 			PyErr_SetString(PyExc_RuntimeError, "Could not complete populating final free spaces index array");
    156 			return NULL;
    157 		}
    158 	}
    159 	
    160 	free(freeindices);
    161 	return freeindices_final;
    162 }
    163 
    164 static PyObject * makeSimplePath_func(PyObject *self, PyObject *args) {
    165 	
    166 	int i;
    167 	
    168 	lash_map_simple_t *map;
    169 	lash_path_simple_t path;
    170 	lash_path_simple_space_t *space;
    171 	lash_path_simple_space_t *nextspace;
    172 	unsigned int *pathindices;
    173 	
    174 	// args
    175 	PyObject *pymap;
    176 	unsigned int index_start;
    177 	unsigned int index_end;
    178 	
    179 	// processing
    180 	unsigned int steps;
    181 	
    182 	// output
    183 	PyObject *path_final;
    184 	
    185 	
    186 	if (!PyArg_ParseTuple(args, "OII", &pymap, &index_start, &index_end))  {
    187 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
    188 		return NULL;
    189 	}
    190 
    191 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
    192 	if (map == NULL) { 
    193 		PyErr_SetString(PyExc_RuntimeError, "Invalid map object");
    194 		return NULL;
    195 	}
    196 	
    197 	if (lash_pathSimpleNew(&path, map,  index_start, index_end) == NULL) {
    198 		PyErr_SetString(PyExc_RuntimeError, "Could not initialize path object");
    199 		return NULL;
    200 	}
    201 	
    202 	lash_pathSimpleNext(&path, &space);
    203 	
    204 	steps = 0;
    205 	
    206 	while (space->index != path.target) {
    207 		lash_pathSimpleStepProcess(&path, map, space, NULL, 0);
    208 		steps++;
    209 		lash_pathSimpleNext(&path, &space);
    210 			
    211 		if (space == NULL) {
    212 			return Py_None;
    213 		}
    214 	}
    215 	
    216 	pathindices = (unsigned int*)calloc(sizeof(unsigned int), steps * 2);
    217 	if (pathindices == NULL){
    218 		PyErr_SetString(PyExc_RuntimeError, "Could not initialize array for final path storage");
    219 		return NULL;
    220 	}
    221 	
    222 	*(pathindices + 0) = space->index;
    223 	
    224 	nextspace = space;
    225 
    226 	steps = 0;
    227 	
    228 	while (nextspace->parent != NULL) {
    229 		steps++;
    230 		space = nextspace;
    231 		nextspace = space->parent;
    232 		*(pathindices + steps) = nextspace->index;
    233 	} 
    234 	
    235 	i = 0;
    236 	
    237 	path_final = PyList_New(steps);
    238 	
    239 	for (i = 0; i < steps; i++) {
    240 		//if (PyList_SetItem(path_final, i, PyBytes_FromFormat("%u", *(pathindices + i))) == -1) {
    241 		if (PyList_SetItem(path_final, i, Py_BuildValue("I", *(pathindices + i))) == -1) {
    242 			PyErr_SetString(PyExc_RuntimeError, "Could not complete populating final path index array");
    243 			if (pathindices != NULL)
    244 				free(pathindices);
    245 			return NULL;
    246 		}
    247 	}
    248 	
    249 	if (pathindices != NULL)
    250 		free(pathindices); 
    251 	
    252 	lash_pathSimpleFree(&path);
    253 	
    254 	return path_final;
    255 }
    256 
    257 static PyObject * pathInit_func(PyObject *self, PyObject *args) {
    258 	
    259 	return Py_BuildValue("i", lash_pathSimpleInit());
    260 	
    261 }
    262 
    263 static PyObject * pathFinish_func(PyObject *self, PyObject *args) {
    264 	lash_pathSimpleFinish();
    265 	return Py_None;
    266 } 
    267 
    268 static PyObject * mapSimpleFree_func(PyObject *self, PyObject *args) {
    269 	lash_map_simple_t *map;
    270 	PyObject *pymap;
    271 	
    272 	if (!PyArg_ParseTuple(args, "O", &pymap)) {
    273 		PyErr_SetString(PyExc_RuntimeError, "Invalid input");
    274 		return NULL;
    275 	}
    276 	
    277 	map = (lash_map_simple_t*)PyCapsule_GetPointer(pymap, "MAP_C_API");
    278 	
    279 	lash_mapSimpleFree(map);  
    280 	free(map);
    281 	
    282 	return Py_None;
    283 }   
    284 
    285 static PyMethodDef PylashgamemapMethods[] = {
    286 	{"mapSimpleInit", (PyCFunction)mapSimpleInit_func, METH_VARARGS, "Initialize a new map object"},
    287 	{"mapSimplePeek", (PyCFunction)mapSimplePeek_func, METH_VARARGS, "Get an obstacle value at a certain index"},
    288 	{"mapSimplePoke", (PyCFunction)mapSimplePoke_func, METH_VARARGS, "Set an obstacle value at a certain index"},
    289 	{"mapSimpleFree", (PyCFunction)mapSimpleFree_func, METH_VARARGS, "Frees resources used by map object"},
    290 	{"getMapSizeUnits", (PyCFunction)getMapSizeUnits_func, METH_VARARGS, "Return with and height in units"},
    291 	{"makeSimplePath", (PyCFunction)makeSimplePath_func, METH_VARARGS, "Returns shortest path between two points using the specified layerpath"},
    292 	{"getPathFreeSpaces", (PyCFunction)getPathFreeSpaces_func, METH_VARARGS, "Get map indices of free spaces from map layer path"},
    293 	{"pathInit", (PyCFunction)pathInit_func, METH_VARARGS, "Initialize the pathfinder library"},
    294 	{"pathFinish", (PyCFunction)pathFinish_func, METH_VARARGS, "Clean the pathfinder library"},
    295 	{NULL, NULL, 0, NULL} 
    296 };
    297 
    298 static struct PyModuleDef lashgamemapmodule = {
    299    PyModuleDef_HEAD_INIT,  
    300    "lashgamemap",   /* name of module */
    301    NULL, /* module documentation, may be NULL */
    302    -1,       /* size of per-interpreter state of the module,
    303                 or -1 if the module keeps state in global variables. */
    304    PylashgamemapMethods
    305 };
    306 
    307 PyMODINIT_FUNC PyInit_lashgamemap(void)
    308 {
    309     return PyModule_Create(&lashgamemapmodule);
    310 }