pathfinding behaviour

Started by
17 comments, last by KnolanCross 10 years, 2 months ago

Add a flag for that, it will make your life easier.

That seems to be what is wrong in your code, you are mixing the g cost (the ACTUAL cost to get to a node from the start) with the f cost (the estimated cost to get to the end).

Edit:

I got to go for today, here is my code that evaluates the neighbors:


static int processCell(pathFindingStruct* path, int xAdjust, int yAdjust, edgeRef* edge, edgeRef* end, const unsigned extraCost){

    if(path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].inClosedList == 1){
       return 1;
    }

    unsigned distance = path->mainGrid[edge->i][edge->j].costSoFar + extraCost;
    if (path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].inOpenList == 0 || distance < path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].costSoFar){

        path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].parent.i = edge->i;
        path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].parent.j = edge->j;

        path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].costSoFar = distance;
        path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].totalCost = path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].costSoFar + path->heuristicDistance(edge->i + yAdjust,edge->j + xAdjust, end->i, end->j);

        if (path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].inOpenList == 0){
            edgeRef* newNode = getEdgeRef(path, edge->i + yAdjust, edge->j + xAdjust, &path->mainGrid[edge->i + yAdjust][edge->j + xAdjust]);
            if (newNode == NULL || (modifiedHeapInsert(path->openList, newNode) == 0)){
                free(newNode);
                return 0;
            }
            path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].inOpenList = 1;
            path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].myRef = newNode;
        }
        else{
            modifiedHeapUpdatedValue(path->openList, path->mainGrid[edge->i + yAdjust][edge->j + xAdjust].myRef);
        }

    }

    return 1;
}

It is in C, using pointers to avoid copies. Important notes:

Edge is the current node.

xAdjust and yAdjust is the move, for instance, if their values are (1, 1) I am moving right and down.

The grid is [y][x] aligned.

The return value is just to check memory errors.

"costSoFar" is g and "totalCost" is f.

extraCost is used because diagonal movements are more expensive.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

Advertisement

this:: ?


foreach (Point dir in ValidMoves(actualX, actualY)) // find lowest  F score
                {
                    int k = D + 1;
                    S = squareMap[dir.X, dir.Y].D;
                    if (S > k)
                    {
                        squareMap[dir.X, dir.Y].F = D + 1 + Math.Abs(dir.X - target.X) + Math.Abs(dir.Y - target.Y);
                        squareMap[dir.X, dir.Y].D = D + 1;
                        squareMap[dir.X, dir.Y].DirX = actualX - dir.X;
                        squareMap[dir.X, dir.Y].DirY = actualY - dir.Y;

doesnt change anything ofc..

maybe im not understanding what you mean...

can you post yoru compare code so i see the difference from mine?

edit: i think my problem is in the heap tbh

for some reason i suspect the new "best" nodes are not going to the top which makes them evaluated after other bad nodes in the open list

i mean for an empty map binary heap should just do

-check all near nodes

-add new to open list

- new best nodes (tipically 1 if diagonal is allowed or 2 otherwise) come to the top of the list

other open list node should never be evaluated after distance 1 which is more than any other node on diagonal has...

Hmm, yes, those are the values you should use.

About the heap, try with a smaller example and print the whole heap to check if it is always the lowest F on top.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

http://imgur.com/qZJCg0D

it seems the open list get not ordered well so sometimes a node that should be on top its not so random open list nodes get evaluated increasing the "noise"

The function that adds to heap does not seem correct to me. I tried to figure out what the proper name of the variables should have been, and it seems rather odd.


void addToOpenList(int x, int y)
{
	openListNumber++;
	Openlist[openListNumber] = new Point(x, y);
	int child = openListNumber;
	int parent = child;
	int F = squareMap[x, y].F;
	Point temp;
	while (child > 1)
	{
		parent = child / 2;
		
		if (squareMap[Openlist[child].X, Openlist[child].Y].F > F)
		{
			temp = Openlist[parent];
			Openlist[parent] = Openlist[child];
			Openlist[child] = temp;
		}
		child = parent;
	}
}

Now this algorithm is much easier to understand. The if statement seems to be a likely culprit. You are comparing the cost of a child node to the cost of the inserted node. Notice however, that in the body of the if statement, you swap the parent (which hasn't been compared to anything yet) with the child node. I think you meant to say the following:


void addToOpenList(int x, int y)
{
	openListNumber++;
	Openlist[openListNumber] = new Point(x, y);
	int child = openListNumber;
	int parent = child;
	Point temp;
	while (child > 1)
	{
		parent = child / 2;
		
		int childCost = squareMap[Openlist[child].X, Openlist[child].Y].F;
		int parentCost = squareMap[OpenList[parent].X, OpenList[parent].Y].F;
		
		if (childCost < parentCost)
		{
			temp = Openlist[parent];
			Openlist[parent] = Openlist[child];
			Openlist[child] = temp;
		}
		child = parent;
	}
}

Now at least the code clearly shows that it's moving the smallest node to the head of the tree. I think there's also a way to terminate the while loop early once the if statement evaluates false (since you're adding only one node and are moving up one branch of a binary tree).

Yo dawg, don't even trip.

THNX that was a huge bug, and improved everything a lot

still its not perfect, there is a small derive anyway :/

update it seems to work decently now after all the small fixes, also i add diagonal tiles cost and it seems to work much better

probably another problem was too many tiles with same cost, ill try to improve that too

dunno how fast it should be thouhg on a 200 x 200 map neraly empty it takes few ms but with many obstacles it take till 30 40 ms (on my core duo)


(i dont get how to multiquote using this forum :/ )

[rollup='How quoting works']

The multi-quote buttons can be used to quote the full text of multiple replies, and works as a toggle style button. To use it, toggle the option on by clicking the button on one or more posts; a small popup should appear in the lower right corner listing how many posts are selected, and providing a reply button. Clicking that reply button should take you to the full post editor with the full text of each selected post provided in the editor.

You can also "selective quote" to reply to small portions of one or more posts. To use this functionality, highlight some text and click the "selective quote" button; the highlighting text will appear in a quote tag in the quick post editor at the bottom of the topic. You can use this function multiple times to add additional snippets to the post editor.

[/rollup]

:)

- Jason Astle-Adams

update it seems to work decently now after all the small fixes, also i add diagonal tiles cost and it seems to work much better

probably another problem was too many tiles with same cost, ill try to improve that too

dunno how fast it should be thouhg on a 200 x 200 map neraly empty it takes few ms but with many obstacles it take till 30 40 ms (on my core duo)

Performance will depend a lot on the language used. I posted my results the other day, you can use it as basis:

http://www.gamedev.net/topic/651968-binary-heap-vs-list-a-my-humble-performance-comparison-updated-with-jps/

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

This topic is closed to new replies.

Advertisement