inline void delete_node(void** seg, void** tail, void *bp) { #ifdef __DEBUG__ printf("Delete node / *seg : %u, tail : %u, bp : %u\n", *seg, *tail, bp); #endif if(isHead(bp) && isTail(bp)) //make list empty { *seg = NULL; *tail = NULL; return; } else if(isHead(bp)) //move head { *seg = getNextNode(*seg); setPrevNode(*seg, *seg); return; } else if(isTail(bp)) //move tail { *tail = getPrevNode(bp); setNextNode(*tail, *tail); return; } void *prev_bp, *next_bp; //link change prev_bp = getPrevNode(bp); next_bp = getNextNode(bp); setNextNode(prev_bp, next_bp); setPrevNode(next_bp, prev_bp); }
CDGNode *getTopPath(CDGNode * node, Stack * changedNodes, Stack * changedBranches) { CDGNode *pathNode = newBlankNode(); CDGNode *temp = pathNode; int branch; while (node) { if (0 != getScore(node)) { stackPush(changedNodes, &node); branch = getOutcome(node); stackPush(changedBranches, &branch); if (isLeaf(node)) { setScore(node, 0); } else { setNextNode(temp, copyToPathNode(newBlankNode(), node)); temp = getNextNode(temp); if (getOutcome(node)) { setBranchInfo(getID(node), 1, getBranchInfo(getID(node), 0)); setTrueNodeSet(temp, getTopPath(getTrueNodeSet(node), changedNodes, changedBranches)); } else { setBranchInfo(getID(node), getBranchInfo(getID(node), 1), 1); setFalseNodeSet(temp, getTopPath(getFalseNodeSet(node), changedNodes, changedBranches)); } } } node = getNextNode(node); } if (temp == pathNode) { deleteNode(pathNode); pathNode = NULL; } else { temp = pathNode; pathNode = getNextNode(pathNode); deleteNode(temp); } return pathNode; }
TNODE *makeFlatTree(const TEXTNODE *list) { const TEXTNODE *listnode = list; qsort(prims, sizeof(prims)/sizeof(prims[0]), sizeof(PRIMTYPE), cmpPrim); if (DEBUG) printf("Making Syntax Tree...\n"); //create command tree from list array TNODE *tree = NIL; TNODE *current = NIL; //split text into expressions and commands... while (listnode) { //printf("List[%d]: %s (%s)\n", i++, listnode->text, dispPrimType(listnode->ntype)); if (tree == NIL) { current = tree = newTreeNode(listnode); } else { current = setNextNode(current, newTreeNode(listnode)); } listnode = listnode->next; } return tree; }
NodeBlock::NodeBlock(NodeBlock * prevBlockNode, CompilerState & state, NodeStatements * s) : NodeStatements(NULL, state), m_ST(state), m_prevBlockNode(prevBlockNode), m_nodeEndingStmt(this) { if(s) { setNextNode(s); setLastStatementPtr(s); } }
inline void attach_node(void** seg, void** tail, void *node) //attach node to linked list { #ifdef __DEBUG__ printf("Attaching node...\n"); #endif if(*seg==NULL || *tail==NULL) //when list is empty { *seg = node; *tail = node; setNextNode(node, node); setPrevNode(node, node); return; } setNextNode(*tail, node); //link node setPrevNode(node, *tail); setNextNode(node, node); //tail invariant : next==tail *tail = node; }
CDGNode *pathToList(CDGNode * head) { assert(NULL != head); Stack *nodeStack = stackNew(sizeof(CDGNode *)); CDGNode *node; CDGNode *list = NULL; postOrder(head, nodeStack); while (!stackIsEmpty(nodeStack)) { stackPop(nodeStack, &node); list = setNextNode(copyToPathNode(newBlankNode(), node), list); } return list; }
CDGNode *newNode(int id, int score, int outcome, const char *expr, CDGNode * trueNodeSet, CDGNode * falseNodeSet, CDGNode * parent, CDGNode * next) { CDGNode *node; node = (CDGNode *) malloc(sizeof(CDGNode)); assert(NULL != node); setID(node, id); setScore(node, score); setOutcome(node, outcome); setExpr(node, expr); setTrueNodeSet(node, trueNodeSet); setFalseNodeSet(node, falseNodeSet); setParent(node, parent); setNextNode(node, next); return node; }
TNODE *makeFlatTree(TEXTNODE *list) { TEXTNODE *listnode = list; TEXTNODE *next; //no need to qsort, already presorted... qsort(prims, sizeof(prims)/sizeof(prims[0]), sizeof(PRIMTYPE), cmpPrim); if (DEBUG) Serial.print("Making Syntax Tree...\n"); //create command tree from list array TNODE *tree = NIL; TNODE *current = NIL; //split text into expressions and commands... while (listnode) { if (DEBUG) { Serial.print(listnode->text); Serial.print(" "); Serial.println(dispPrimType(listnode->type)); } if (listnode->type == ID) { if (strcmp(listnode->text, "TRUE") == 0) { listnode->text = "1"; listnode->type = NUM; } if (strcmp(listnode->text, "FALSE") == 0) { listnode->text = "0"; listnode->type = NUM; } } if (tree == NIL) { current = tree = newTreeNode(listnode); } else { current = setNextNode(current, newTreeNode(listnode)); } free(listnode->text); next = listnode->next; free(listnode); listnode = next; } return tree; }
CDGNode *buildFeasiblePath(CDGNode * node, CDGNode * list) { while (node && 0 == nodeExists(list, getID(node))) { node = getNextNode(node); } if (NULL == node) return NULL; CDGNode *out = NULL; out = copyToPathNode(newBlankNode(), node); setTrueNodeSet(out, buildFeasiblePath(getTrueNodeSet(node), list)); setFalseNodeSet(out, buildFeasiblePath(getFalseNodeSet(node), list)); setNextNode(out, buildFeasiblePath(getNextNode(node), list)); return out; }
//------------------------------------------------------------ //attempt to find a path void StealthFoe::findPath(){ int startX=p.pos.x/fieldScale; int startY=p.pos.y/fieldScale; startX=MAX(0,MIN(startX,fieldW-1)); startY=MAX(0,MIN(startY,fieldH-1)); //clear out the vectors clearPathfindingLists(); //add the start tile to the openList tile * start = new tile(); // startX=testo.p.pos.x; // startY=testo.p.pos.y; start->x=startX; start->y=startY; start->g=0; start->h=getDistToGoal(start->x,start->y); start->f= start->g+start->h; openList.push_back(start); //tile * parent=t; bool goalFound=false; bool doneSearching=false; while(!doneSearching){ //find the lowest F value in the open list int lowestID=0; for (int i=0; i<openList.size(); i++){ if(openList[i]->f <= openList[lowestID]->f) lowestID=i; } //move this tile to the closed list closedList.push_back(openList[lowestID]); //remove it from the open list openList.erase(openList.begin()+lowestID); //explore this tile tile * current=closedList[closedList.size()-1]; //if this was the goal tile, we're done if(current->x==goalX && current->y==goalY){ goalFound=true; doneSearching=true; } //check the 8 tiles aorund this one for (int x=-1; x<=1; x++){ for (int y=-1; y<=1; y++){ int xPos=current->x+x; int yPos=current->y+y; //make sure this tile is not the current one or off the grid if (xPos>=0 && xPos<fieldW && yPos>=0 && yPos<fieldH && (x!=0 || y!=0) ){ int pixelPos=yPos*fieldW+xPos; //MAKE A FUNCTION FOR THIS //check if the tile is impassible ANYTHING WORKS FOR THE STEALTH FOE! if (true){ //don't add any tile that is adjacent to a wall //this is to help keep the path a little less hugging one wall bool nextToWall=false; //AND HE DOESN'T GIVE A F**K ABOUT WALLS EITHER if (!nextToWall){ //check that the tile is not in the closed list bool inClosedList=false; //assume it isn't for (int c=0; c<closedList.size(); c++){ if (closedList[c]->x==xPos && closedList[c]->y==yPos) inClosedList=true; } if (!inClosedList){ //check to see if it is already in the open list int openListID=-1; for (int o=0; o<openList.size(); o++){ if (openList[o]->x==xPos && openList[o]->y==yPos) openListID=o; } //add it to the open list if it isn't already there if (openListID==-1){ tile * t = new tile(); t->x=xPos; t->y=yPos; if (y==0 || x==0) t->g=current->g+horzDist; else t->g=current->g+diagDist; t->h=getDistToGoal(xPos, yPos); t->f=t->g+t->h; t->parent=current; openList.push_back(t); //if we just added the goal to the open list, we're done //THIS WILL NOT ALWAYS BE AS ACURATE AS WAITING UNTIL THE GOAL IS ADDED TO THE CLOSED LIST //BUT IT IS FASTER if (t->x==goalX && t->y==goalY){ doneSearching=true; goalFound=true; //add it to closed list so it will be added to the route closedList.push_back(t); //remove it from the open list openList.erase(openList.begin()+openList.size()-1); } }else{ //if it is there see if this path is faster int newG; //measure distance to the tile based on g if (y==0 || x==0) newG=current->g+horzDist; else newG=current->g+diagDist; if (newG<openList[openListID]->g){ openList[openListID]->g=newG; //set g to be the new, shorter distance openList[openListID]->f=newG+openList[openListID]->h; //reset the f value for this tile openList[openListID]->parent=current; //change the parent } } } } } } } } //if we're out of tiles, there is no path if (openList.size()==0) doneSearching=true;//testing } //if it found a path, add it to the route if (goalFound){ pathFound=true; //start with the goal and work backwards route.push_back(closedList[closedList.size()-1]); while(! (route[route.size()-1]->x==startX && route[route.size()-1]->y==startY)){ route.push_back(route[route.size()-1]->parent); } //reset the next node to start from the beginning nextNode=route.size()-1; setNextNode(); }else{ pathFound=false; } }
//------------------------------------------------------------ void Foe::update(){ if (! *paused){ bool frozen=false; if (freezeTimer>0 && freezeTimer%2==0) frozen=true; if (route.size()>2 && !frozen){ //reset the particle p.resetForce(); //atract the controler to the next node float atraction=moveAtraction; p.addAttractionForce(moveParticle, p.pos.distance(moveParticle.pos)*1.5, atraction); moveAtraction+=moveAtractionIncrease; //get force from the vector field. ofVec2f frc; frc = VF->getForceFromPos(p.pos.x, p.pos.y); //stealth gets almost no resistance from walls if (type=="stealth") frc*=0.3; p.addForce(frc.x, frc.y); //dampen and update the particle p.addDampingForce(); p.update(); } //see if we're ready to go to the next node if (p.pos.distance(moveParticle.pos)<nextNodeRad){ setNextNode(); } //if we're at the end, bolt off screen if (ofDist(p.pos.x,p.pos.y,goalX*fieldScale,goalY*fieldScale)<15){ //reachedTheEnd=true; endBolt=true; //set the move particle just off screen //check which gate this foe is using if (goalX>goalY) moveParticle.pos.x+=10; else moveParticle.pos.y+=10; } //reduce freezeTimer. if it is above 0 the foe is frozen freezeTimer--; } //moving the foe off screen if it has reached the end if (endBolt){ //reset the particle p.resetForce(); //atract the controler to the next node float atraction=moveAtraction*5; p.addAttractionForce(moveParticle, p.pos.distance(moveParticle.pos)*1.5, atraction); moveAtraction+=moveAtractionIncrease; //dampen and update the particle p.addDampingForce(); p.update(); //if we've reach the move particle, the foe is done if ( (goalX>goalY && p.pos.x>moveParticle.pos.x) || (goalY>goalX && p.pos.y>moveParticle.pos.y) ) { reachedTheEnd=true; } } //test if the foes is dead if (hp<=0) dead=true; }
//------------------------------------------------------------ //attempt to find a path void Foe::standardFindPath(){ int startX=p.pos.x/fieldScale; int startY=p.pos.y/fieldScale; startX=MAX(0,MIN(startX,fieldW-1)); startY=MAX(0,MIN(startY,fieldH-1)); //clear out the vectors clearPathfindingLists(); //add the start tile to the openList tile * start = new tile(); // startX=testo.p.pos.x; // startY=testo.p.pos.y; start->x=startX; start->y=startY; start->g=0; start->h=getDistToGoal(start->x,start->y); start->f= start->g+start->h; openList.push_back(start); //tile * parent=t; bool goalFound=false; bool doneSearching=false; while(!doneSearching){ //find the lowest F value in the open list int lowestID=0; for (int i=0; i<openList.size(); i++){ if(openList[i]->f <= openList[lowestID]->f) lowestID=i; } //move this tile to the closed list closedList.push_back(openList[lowestID]); //remove it from the open list openList.erase(openList.begin()+lowestID); //explore this tile tile * current=closedList[closedList.size()-1]; //if this was the goal tile, we're done if(current->x==goalX && current->y==goalY){ goalFound=true; doneSearching=true; } //check the 8 tiles aorund this one for (int x=-1; x<=1; x++){ for (int y=-1; y<=1; y++){ int xPos=current->x+x; int yPos=current->y+y; //make sure this tile is not the current one or off the grid if (xPos>=0 && xPos<fieldW && yPos>=0 && yPos<fieldH && (x!=0 || y!=0) ){ int pixelPos=yPos*fieldW+xPos; //MAKE A FUNCTION FOR THIS //check if the tile is impassible if (wallPixels[pixelPos]==255){ //don't add any tile that is adjacent to a wall //this is to help keep the path a little less hugging one wall bool nextToWall=false; for (int x2=-1; x2<=1; x2++){ for (int y2=-1; y2<=1; y2++){ int pixelPos2=(yPos+y2)*fieldW+(xPos+x2); if (wallPixels[pixelPos2]==0) nextToWall=true; } } if (!nextToWall){ //check that the tile is not in the closed list bool inClosedList=false; //assume it isn't for (int c=0; c<closedList.size(); c++){ if (closedList[c]->x==xPos && closedList[c]->y==yPos) inClosedList=true; } if (!inClosedList){ //check to see if it is already in the open list int openListID=-1; for (int o=0; o<openList.size(); o++){ if (openList[o]->x==xPos && openList[o]->y==yPos) openListID=o; } //add it to the open list if it isn't already there if (openListID==-1){ tile * t = new tile(); t->x=xPos; t->y=yPos; if (y==0 || x==0) t->g=current->g+horzDist; else t->g=current->g+diagDist; t->h=getDistToGoal(xPos, yPos); t->f=t->g+t->h; t->parent=current; openList.push_back(t); //if we just added the goal to the open list, we're done //THIS WILL NOT ALWAYS BE AS ACURATE AS WAITING UNTIL THE GOAL IS ADDED TO THE CLOSED LIST //BUT IT IS FASTER if (t->x==goalX && t->y==goalY){ doneSearching=true; goalFound=true; //add it to closed list so it will be added to the route closedList.push_back(t); //remove it from the open list openList.erase(openList.begin()+openList.size()-1); } }else{ //if it is there see if this path is faster int newG; //measure distance to the tile based on g if (y==0 || x==0) newG=current->g+horzDist; else newG=current->g+diagDist; if (newG<openList[openListID]->g){ openList[openListID]->g=newG; //set g to be the new, shorter distance openList[openListID]->f=newG+openList[openListID]->h; //reset the f value for this tile openList[openListID]->parent=current; //change the parent } } } } } } } } //if we're out of tiles, there is no path if (openList.size()==0) doneSearching=true;//testing } //if it found a path, add it to the route if (goalFound){ //the memory positions pointed to in route may have already been destroyed route.clear(); //first, clear the old route pathFound=true; //start with the goal and work backwards route.push_back(closedList[closedList.size()-1]); while(! (route[route.size()-1]->x==startX && route[route.size()-1]->y==startY)){ route.push_back(route[route.size()-1]->parent); } //reset the next node to start from the beginning nextNode=route.size()-1; setNextNode(); }else{ pathFound=false; } //If it looks like the foe was inked over trying to move along path int minListSize=3; //how small the closed list must be to move along the path if (!pathFound && closedList.size()<minListSize && nextNode>2){ setNextNode(); //go to the next node p.pos=moveParticle.pos; //move the foe there //keep the foe in the maze in case garbage values are returned p.pos.x=CLAMP(p.pos.x,11*fieldScale,155*fieldScale); p.pos.y=CLAMP(p.pos.y,11*fieldScale,115*fieldScale); standardFindPath(); //try again recursievly } }