int main(void) { INIT(); long int i; Object list = List_Create(); Object iterator; for(i = 0; i < NODES; i++) { List_PushFront(list, INT_AS_OBJECT(i)); }; List_Sort(list); ; for(iterator = List_First(list), i = 0; !ListIterator_ThisEnd(iterator); ListIterator_Next(iterator), i++) { if(OBJECT_AS_INT(ListIterator_ThisData(iterator)) != i) { DEBUG("Got %li, but %li expected.\n", OBJECT_AS_INT(ListIterator_ThisData(iterator)), i); return 1; }; }; Object_Release(list); return 0; };
int main(void) { INIT(); int i, j; Object list = List_Create(); for(j = 0; j < TIMES; j++) { Object front, back; for(i = 0; i < NODES; i++) { if(i & 1) { List_PushBack(list, INT_AS_OBJECT(i)); } else { List_PushFront(list, INT_AS_OBJECT(i)); }; }; front = List_First(list); back = List_Last(list); while(!ListIterator_ThisEnd(front)) { ListIterator_Next(front); ListIterator_Prev(back); }; if(!ListIterator_ThisBegin(back)) { return 1; }; List_Clean(list); }; Object_Release(list); return 0; };
void test_algorithm(void) { int padding = 1; list_t *imageList = NULL; btree_t *tree; list_t *treeDumpList = NULL; list_t *fileListIter = NULL; int i = 0; char filename[10]; int success = 1; int initsize = 512; srand((unsigned int)time(NULL)); for (i = 0; i < 2800; i++) { list_t *node = NULL; image_t *img = NULL; img = (image_t *)calloc(1, sizeof(image_t)); node = List_Create(); sprintf(filename, "%d.png", i); img->w = 5 + rand() % 20; img->h = 5 + rand() % 20; Util_CopyString(&img->filename, filename); node->payload.type = Payload_Image; node->payload.data = img; List_PushFront(&imageList, node); } List_Sort(&imageList); tree = BTree_Create(); tree->rect.x = 0; tree->rect.y = 0; tree->rect.w = initsize; tree->rect.h = initsize; do { success = 1; for (fileListIter = imageList; fileListIter != NULL; fileListIter = fileListIter->next) { if (BTree_Insert(tree, (image_t *)fileListIter->payload.data, padding) == NULL) { printf("Shit happens\n"); success = 0; break; } } if (!success) { BTree_Destroy(tree); tree = BTree_Create(); tree->rect.x = 0; tree->rect.y = 0; initsize = Util_NextPOT(initsize+1); tree->rect.w = initsize; tree->rect.h = initsize; } } while (!success); printf("-----\n"); List_Destroy(imageList, ListDestroy_List|ListDestroy_PayLoad); treeDumpList = BTree_DumpToList(tree, BTreeTraverse_PostOrder); { list_t *iter = NULL; bitmap_t *canvas = NULL; rect_t *rect = NULL; canvas = Bitmap_Create(initsize, initsize); iter = treeDumpList; for (iter = treeDumpList; iter != NULL; iter = iter->next) { rect = (rect_t *)iter->payload.data; if (rect->image != NULL && rect->image->filename != NULL) { int argb = 0; bitmap_t *pad = NULL; bitmap_t *png = NULL; png = Bitmap_Create(rect->image->w, rect->image->h); pad = Bitmap_Create(rect->image->w + rect->padding * 2, rect->image->h + rect->padding * 2); argb = rand(); argb |= 0xFF000000; Bitmap_Clean(png, argb); Bitmap_Clean(pad, 0); Bitmap_CopyPasteBitmap(pad, png, rect->padding, rect->padding); Bitmap_CopyPasteBitmap(canvas, pad, rect->x, rect->y); Bitmap_Destroy(png); Bitmap_Destroy(pad); } } Bitmap_WriteAsPNG(canvas, "canvas.png"); Bitmap_Destroy(canvas); } List_Destroy(treeDumpList, ListDestroy_List); if (tree != NULL) BTree_Destroy(tree); memtrack_list_allocations(); }
int main(void) { INIT(); long int i; int l = 10, r = 5; Object list = List_Create(); Object list2 = List_Create(); Object temp_list; Object front, back; // list2 = (0 1 2 3 4 5 6 ... 148 149) for(i = 0; i < l + r; i++) { List_PushBack(list2, INT_AS_OBJECT(i)); }; // list = (99998 99996 ... 8 6 4 2 0 1 3 5 7 9 ... 99997 99999 ) for(i = 0; i < NODES; i++) { if(i & 1) { List_PushBack(list, INT_AS_OBJECT(i)); } else { List_PushFront(list, INT_AS_OBJECT(i)); }; }; for(front = List_First(list), i = 0; i < NODES / 2; ListIterator_Next(front), i++) { List_AddAfterPosition(list2, INT_AS_OBJECT(l - 1 + i), ListIterator_ThisData(front)); }; for(back = List_Last(list), i = 0; i < NODES / 2; ListIterator_Prev(back), i++) { List_AddAfterPosition(list2, INT_AS_OBJECT(l + NODES / 2 - 1), ListIterator_ThisData(back)); }; front = List_IteratorFromPosition(list2, INT_AS_OBJECT(l)); TEST("Checking for correctness of IteratorFromPosition after AddList{Before|After}", OBJECT_AS_INT(ListIterator_ThisData(front)) == (NODES & (~1)) - ((!(NODES & 1)) * 2)); back = List_IteratorFromPosition(list2, INT_AS_OBJECT(l + NODES - 1)); TEST("Checking for correctness of IteratorFromPosition after AddList{Before|After}", OBJECT_AS_INT(ListIterator_ThisData(back)) == (NODES & (~1)) - 1 + ((NODES & 1) * 2)); temp_list = List_SublistBetweenIterators(list2, front, back); front = List_First(temp_list); back = List_Last(temp_list); for(i = 1; i < NODES / 2; i++) { if(OBJECT_AS_INT(ListIterator_ThisData(front)) != OBJECT_AS_INT(ListIterator_ThisData(back)) + 1) { DEBUG("Got %li and %li.\n", OBJECT_AS_INT(ListIterator_ThisData(front)), OBJECT_AS_INT(ListIterator_ThisData(back))); return 1; }; ListIterator_Next(front); ListIterator_Prev(back); }; Object_Release(list); Object_Release(list2); Object_Release(temp_list); return 0; };
navpath_t* NavRep_PathCreate_Internal(navmesh_t* navmesh, const vec2_t src, navpoly_t* pathpoly_src, const vec2_t dest, navpoly_t* pathpoly_dest) { int ms = System_Milliseconds(); // increment the frame code (frame code is used in place of open/closed list) int frame = ++navmesh->frame_cnxn; if ( pathpoly_src == pathpoly_dest ) { // if we're in the same pathpoly, just go there navpathwaypt_t* waypoint; path_last = (navpath_t*)ALLOCATE(navpath_t); path_last->waypoints.first = NULL; path_last->waypoints.last = NULL; M_CopyVec2(dest, path_last->pos); M_CopyVec2(dest, path_last->src); M_CopyVec2(src, path_last->dest); waypoint = NavPathWaypt_Create(src); waypoint->bridge = pathpoly_src->bridge2 ? pathpoly_src : NULL; List_PushFront(&path_last->waypoints, waypoint); path_last->waypoint = path_last->waypoints.first; // List_PushFront(&navpaths, path_last); return path_last; } if ( !pathpoly_dest->bridge2 && NavMesh_Trace(navmesh, src, dest) ) { // if we can trace, just go there navpathwaypt_t* waypoint; path_last = (navpath_t*)ALLOCATE(navpath_t); path_last->waypoints.first = NULL; path_last->waypoints.last = NULL; M_CopyVec2(dest, path_last->pos); M_CopyVec2(dest, path_last->src); M_CopyVec2(src, path_last->dest); waypoint = NavPathWaypt_Create(src); List_PushFront(&path_last->waypoints, waypoint); path_last->waypoint = path_last->waypoints.first; // List_PushFront(&navpaths, path_last); return path_last; } { // create our heap heap_t heap; Heap_Init(&heap, 16384, Heap_Compare_PathPolyCnxn); // push all initial cnxns onto heap { navpolyedge_t* edge = pathpoly_src->edges; while ( edge ) { navpolycnxn_t* cnxn = edge->cnxns.first; while ( cnxn ) { navpolygate_t* gate = cnxn->gates; while ( gate ) { // initialize costs gate->distance = path_sqrt(M_GetDistanceSqVec2(src, gate->position)); gate->cost = gate->distance + path_sqrt(M_GetDistanceSqVec2(dest, gate->position)); gate->from = NULL; gate->frame = frame; // add to heap Heap_Push(&heap, gate); gate = gate->next; } cnxn = cnxn->next; } edge = edge->next; } } while ( !Heap_IsEmpty(&heap) ) { // extract min cost gate navpolygate_t* gate = (navpolygate_t*)Heap_Pop(&heap); if ( gate->cnxn->into == pathpoly_dest ) { if ( fabs(gate->distance - gate->cost) < PATH_EPSILON ) { // found a path, finalize it path_last = NavRep_PathFinalize(navmesh, src, dest, gate); NAV_PRINTF("NavRep_PathCreate succeeded, took %d milliseconds\n", System_Milliseconds() - ms); // term the heap Heap_Term(&heap); // List_PushFront(&navpaths, path_last); return path_last; } else { gate->distance += path_sqrt(M_GetDistanceSqVec2(gate->position, dest)); gate->cost = gate->distance; Heap_Update(&heap, gate); continue; } } // relax all adjacent gates { navpoly_t* pathpoly = gate->cnxn->into; navpolyedge_t* pathpoly_edge = pathpoly->edges; while ( pathpoly_edge ) { navpolycnxn_t* pathpoly_cnxn = pathpoly_edge->cnxns.first; while ( pathpoly_cnxn ) { navpolygate_t* pathpoly_gate = pathpoly_cnxn->gates; while ( pathpoly_gate ) { float distance = 1.0f + gate->distance + path_sqrt(M_GetDistanceSqVec2(pathpoly_gate->position, gate->position)); float cost = distance + path_sqrt(M_GetDistanceSqVec2(pathpoly_gate->position, dest)); if ( pathpoly_gate->frame != frame ) { pathpoly_gate->cost = cost; pathpoly_gate->distance = distance; pathpoly_gate->frame = frame; pathpoly_gate->from = gate; Heap_Push(&heap, pathpoly_gate); } // $todo: why is it okay (faster + just as accurate) to compare distance here rather than cost???? else if ( (pathpoly_gate->distance > distance) ) { pathpoly_gate->cost = cost; pathpoly_gate->distance = distance; pathpoly_gate->from = gate; Heap_Update(&heap, pathpoly_gate); } pathpoly_gate = pathpoly_gate->next; } pathpoly_cnxn = pathpoly_cnxn->next; } pathpoly_edge = pathpoly_edge->next; } } } NAV_PRINTF("NavRep_PathCreate failed, took %d milliseconds\n", System_Milliseconds() - ms); // term the heap Heap_Term(&heap); } return NULL; }