void minheapify(binaryheap heap, int i) { int left = 2*i; int right = 2*i+1; int smallest = i; if(left <= heap.getsize() && heap.getnode(left).fcost < heap.getnode(smallest).fcost) smallest = left; if(right <= heap.getsize() && heap.getnode(right).fcost < heap.getnode(smallest).fcost) smallest = right; if(i != smallest) { heap.swapwithparent(smallest);//swap heap[i] and heap[smallest] minheapify(heap, smallest); } }
List<int[]> pathlist = null; //list holding x and y values of a path, used in findpath, null if no path found #endregion Fields #region Methods public void findpath(int startX, int startY, int endX, int endY, int range) { binaryheap openset = new binaryheap(new heapnode(0, estimatehcost(startX, startY, endX, endY), startX, startY, null,0)); List<heapnode> closedset = new List<heapnode>(); heapnode parentnode = openset.getnode(1); heapnode temp; //temporary node for recalculating better paths bool isinclosedset; if(tiles == null) { while(openset.getsize() != 0) { //check if the parent node is the goal, if so the best path is found if(parentnode.x == endX && parentnode.y == endY) { tracepath(closedset[closedset.Count-1]); return; //exit the method } //make the parent node the tile with the lowest fcost parentnode = openset.getlowestfcostnode(); //remove parent node from the open set openset.removenode(); //add parent node to the closed set closedset.Add(parentnode); //add all legal adjacent tiles to the list for(int i=-1; i<=1; i++) { for(int j=-1; j<=1; j++) { if(i != j) //don't check the parent tile or 1,1 or -1,-1, those are illegal { //checking to see if in closed list isinclosedset = false; for(int k=0; k<closedset.Count; k++) { if(closedset[k].x == parentnode.x+i && closedset[k].y == parentnode.y+j) isinclosedset = true; } //checks if........ if((parentnode.x+i >=0 && parentnode.x+i < tilemap.GetLength(1) && parentnode.y+j >=0 && parentnode.y+j < tilemap.GetLength(0) //A. tilemap goes that far && tilemap[parentnode.x+i, parentnode.y+j] != null //that tilemap space has a gameobject && tilemap[parentnode.x+i, parentnode.y+j].GetComponent<Tile>() != null //B. that tilemap space has a tile && tilemap[parentnode.x+i,parentnode.y+j].GetComponent<Tile>().getifobstacle() == false //C.if not obstructed && isinclosedset == false//D. the tile is not on the closed list && parentnode.gcost+addtogcost(parentnode.x, parentnode.y, parentnode.x+i, parentnode.y+j) <= range) //the new gcost minus engagement penalty is not higher than the movement range && (openset.getnode(parentnode.x+i, parentnode.y+j) == null//E. not on openlist || parentnode.gcost+addtogcost(parentnode.x, parentnode.y, parentnode.x+i, parentnode.y+j) < parentnode.gcost))//F. gscore less than parent { //the outer if loop is important for tracing the path if(openset.getnode(parentnode.x+i, parentnode.y+j) == null) //if not on the open set { openset.addtoheap(parentnode.gcost+addtogcost (parentnode.x, parentnode.y, parentnode.x+i, parentnode.y+j), estimatehcost(parentnode.x+i, parentnode.y+j, endX, endY), parentnode.x+i, parentnode.y+j, parentnode);//add it } else if(parentnode.gcost+addtogcost(parentnode.x, parentnode.y, parentnode.x+i, parentnode.y+j) +estimatehcost(parentnode.x+i, parentnode.y+j, endX, endY) < openset.getnode(parentnode.x+i, parentnode.y+j).parent.fcost) //if on open set, see if this is the better path { //reset the parent to parentnode temp = openset.getnode(parentnode.x+i, parentnode.y+j); temp.parent = closedset[closedset.Count-1]; //recalculate gcost and hcost temp.gcost = temp.parent.gcost+addtogcost(parentnode.x, parentnode.y, parentnode.x+i, parentnode.y+j); temp.hcost = estimatehcost(temp.x, temp.y, endX, endY); openset.replacenode(temp); } } } } } } } pathlist = null; return; //if a path is not found }