void resizeMap(map m, size_t scale){ void** old = m->values; size_t size = scale * m->size; size_t oldSize = m->size; m->size = size; m->values = malloc(sizeof(void*) * size); fillEmpty(m); size_t index; for(index = 0; index < oldSize; index++){ linkedList list = old[index]; if(list){ while(!linkedListIsEmpty(list)){ linkedNode node = removeLinkedListHead(list); var v = node->content; m->count--; //Don't double count items. insertMapValue(v->name, v->content, m); free(v); free(node); } free(list); } } free(old); }
/** * Deallocates every link in the list including the sentinels, * and frees the list itself. */ void linkedListDestroy(struct LinkedList* list) { while (!linkedListIsEmpty(list)) { linkedListRemoveFront(list); } free(list->frontSentinel); free(list->backSentinel); free(list); }
void removeMapValue(string key, map m){ size_t index = hashKey(key) % m->size; linkedList list = m->values[index]; if(list){ linkedNode node = list->head; var content = (var) node->content; if(streq(key, content->name)){ removeLinkedListHead(list); free(node); m->count--; if(linkedListIsEmpty(list)){ free(list); m->values[index] = NULL; } return; } content = (var) node->next->content; while(node->next && !streq(key, content->name)){ node = node->next; content = (var) node->next->content; } if(node->next){ linkedNode removed = node->next; node->next = removed->next; free(removed); m->count--; } } }
static void aStar( const BNavmesh *navmesh, const BTriangle *startTriangle, const BTriangle *endTriangle, const BVector *destination, BAStarOutput *output ) { assert( navmesh != NULL ); assert( startTriangle != NULL ); assert( endTriangle != NULL ); assert( destination != NULL ); assert( output != NULL ); assert( isPointInsideNavmeshTriangle( navmesh, destination, endTriangle) ); assert( startTriangle->connectedComponent == endTriangle->connectedComponent ); BLinkedList openList, closedList; linkedListInit( &openList, sizeof( BAStarNode ), NULL ); linkedListInit( &closedList, sizeof( BAStarNode ), NULL ); BAStarNode startNode; startNode.cost = 0; startNode.previousTriangle = NULL; startNode.triangle = startTriangle; startNode.heuristic = heuristic( startNode.triangle, destination ); linkedListPrepend( &openList, &startNode ); BAStarNode arrivalNode; while ( 1 ) { BAStarNode current; assert( !linkedListIsEmpty( &openList ) ); // TODO Handle case where no path exists linkedListGetHead( &openList, ¤t ); linkedListRemoveHead( &openList ); linkedListPrepend( &closedList, ¤t ); if ( current.triangle == endTriangle ) { arrivalNode = current; break; } for ( int neighborIndex = 0; neighborIndex < 3; neighborIndex++ ) { const int neighborTriangleIndex = current.triangle->neighbours[neighborIndex]; assert( neighborTriangleIndex < navmesh->numTriangles ); if ( neighborTriangleIndex < 0 ) { continue; } const BTriangle *neighborTriangle = &navmesh->triangles[neighborTriangleIndex]; const float newCost = current.cost + movementCost( current.triangle, neighborTriangle ); BAStarNode occurenceInOpenList; int inOpenList = linkedListFind( &openList, isTriangle, ( void * ) neighborTriangle, &occurenceInOpenList ); if ( inOpenList ) { if ( newCost < occurenceInOpenList.cost ) { linkedListRemove( &openList, isTriangle, ( void * ) ¤t.triangle ); inOpenList = 0; } } const int inClosedList = linkedListFind( &closedList, isTriangle, ( void * ) neighborTriangle, NULL ); if ( !inOpenList && !inClosedList ) { BAStarNode newNode; newNode.cost = newCost; newNode.triangle = neighborTriangle; newNode.heuristic = heuristic( newNode.triangle, destination ); newNode.previousTriangle = current.triangle; linkedListInsertBefore( &openList, &newNode, hasBetterRank ); } } } output->numTriangles = 0; { const BTriangle *currentTriangle = endTriangle; while ( currentTriangle != NULL ) { assert( currentTriangle >= 0 ); BAStarNode node; verify( linkedListFind( &closedList, isTriangle, ( void * ) currentTriangle, &node ) ); currentTriangle = node.previousTriangle; output->numTriangles++; } } output->triangles = malloc( sizeof( BTriangle * ) * output->numTriangles ); { int nextPathTriangleIndex = output->numTriangles - 1; const BTriangle *currentTriangle = endTriangle; while ( currentTriangle != NULL ) { assert( currentTriangle >= 0 ); assert( nextPathTriangleIndex >= 0 ); assert( nextPathTriangleIndex < output->numTriangles ); output->triangles[nextPathTriangleIndex] = currentTriangle; BAStarNode node; verify( linkedListFind( &closedList, isTriangle, ( void * ) currentTriangle, &node ) ); currentTriangle = node.previousTriangle; nextPathTriangleIndex--; } } linkedListFree( &openList ); linkedListFree( &closedList ); assert( output->triangles[0] == startTriangle ); assert( output->triangles[output->numTriangles - 1] == endTriangle ); }
TYPE linkedListBack(struct linkedList *q){ assert(!linkedListIsEmpty(q)); return q->backSentinel->prev->value; }
TYPE linkedListFront(struct linkedList *q){ assert(!linkedListIsEmpty(q)); return q->frontSentinel->next->value; }
void linkedListRemoveBack(struct linkedList *q){ assert(!linkedListIsEmpty(q)); _removeLink(q, q->backSentinel->prev); }
void linkedListRemoveFront(struct linkedList *q){ assert(!linkedListIsEmpty(q)); _removeLink(q, q->frontSentinel->next); }