Advertisement

Where can I find source code for simple A* path-finding?

Started by July 15, 2005 11:23 PM
2 comments, last by DarkCybo1 19 years, 4 months ago
I've read the A* for Beginners tutorial, and understand the concepts, but for some reason, I'm unable to successfully code it, as my program can only pull off simple pathfinding, and when it comes to more complex path-finding, the program always ends up running into some wall. I've looked at the tutorial's source code, but the way the author coded it makes it hard to understand for me.. Where can I find source code for simple A* pathfinding?
Hey babe.
Here is a suggestion, why don't you try Dijkstra's search first? It is a precursor to A* and a lot simpler (but also a lot less efficient). Wikipedia has an article on it.
Turring Machines are better than C++ any day ^_~
Advertisement
DarkCybo1

There is a tutorial, at the end of which there is a link to a couple of A* path finding demos, on Patrick Lester's webpage, though I don't know how "simple" the source is by your standards.
Alright, thanks for the help, but I'm having some minor problems with my pathfinding. I can manage to get the parent to the target even in complicated paths, but take a look at this:

http://img327.imageshack.us/img327/3364/patherror6rr.jpg

The blue line represents the path from start to finish, but "PL" (player) ALWAYS goes through corner before continuing his path to the target (corner circled in red)..

Anyone know why this is? Sorry if my code is complicated, but any help is appreciated..

#include <cstdlib>#include <list>#include <vector>#include <windows.h>#include <fstream>#include <iostream>class cTile{   public:            int f, g, h, tile;};class cMap{   public:            void CalculateTiles()      {         int tileDir = 0;         int lowestFx, lowestFy;         int pathG = 0, addedGCost = 0, origAddedGCost = 0;         int tempGCost = 0, origGCost = 0;                  cTile* lowestF = NULL;         cTile* betterPath = NULL;                  int betterPathX, betterPathY, origPathG;                              while(!FoundTarget())         {            pathG = 0;            tileDir = 0;                        origAddedGCost = addedGCost;                        lowestF = NULL;            betterPath = NULL;                        Sleep(200);                        //CALCULATE TILES               for(int y = parentY - 1; y < parentY + 2; y++)            {               for(int x = parentX - 1; x < parentX + 2; x++)               {                  tileDir++;                                 if(( (x < 0 && x >= width) || (y < 0 && y >= height) ) ||                     onClosedList(&tiles[x][y])                     )                        continue;                                          if(tileDir % 2 && parentY != y)                  {                     if(y == parentY - 1)                     {                        if(x == parentX - 1)                        {                           if((tiles[x + 1][y].tile == 1) || (tiles[x][y + 1].tile == 1))                              continue;                        }                                                if(x == parentX + 1)                        {                           if((tiles[x - 1][y].tile == 1) || (tiles[x][y + 1].tile == 1))                              continue;                        }                     } else if(y == parentY + 1)                     {                        if(x == parentX - 1)                        {                           if((tiles[x + 1][y].tile == 1) || (tiles[x][y - 1].tile == 1))                              continue;                        }                                                if(x == parentX + 1)                        {                           if((tiles[x - 1][y].tile == 1) || (tiles[x][y - 1].tile == 1))                              continue;                        }                     }                  }                                 //Check if it's straight across or diagnoal                  if(!(tileDir % 2) || parentY == y)                  {                     if(!onOpenList(&tiles[x][y]) && origAddedGCost == addedGCost)                     {                        addedGCost += 10;                     }                                          tiles[x][y].g = addedGCost;                                       } else                  {                     if(!onOpenList(&tiles[x][y]) && origAddedGCost == addedGCost)                     {                        addedGCost += 14;                     }                                          tiles[x][y].g = addedGCost;                                       } //End check                                 tiles[x][y].h = (abs(targetX - x) + abs(targetY - y)) * 10;                  tiles[x][y].f = tiles[x][y].g + tiles[x][y].h;                                 AddToOpenList(&tiles[x][y]);                                    //Find tile with the lowest F                  if(lowestF == NULL)                  {                     lowestF = &tiles[x][y];                     lowestFx = x;                     lowestFy = y;                  } else                  {                     if(lowestF->f > tiles[x][y].f)                     {                        lowestF = &tiles[x][y];                        lowestFx = x;                        lowestFy = y;                     }                  }                              }                           tileDir = 0;            }                        //Set parent square to tile with lowest f            AddToClosedList(&tiles[parentX][parentY]);            pathG += lowestF->g;            parentX = lowestFx;            parentY = lowestFy;                        tileDir = 0;                        if(FoundTarget())               break;                           drawMap();                        origPathG = pathG;                        //Check to see if any other paths are better            for(int y = parentY - 1; y < parentY + 2; y++)            {               for(int x = parentX - 1; x < parentX + 2; x++)               {                  tileDir++;                                    if(( (x < 0 && x >= width) || (y < 0 && y >= height) ) ||                     onClosedList(&tiles[x][y]) || !onOpenList(&tiles[x][y])                     )                        continue;                                       //Don't allow corner cutting                  if(tileDir % 2 && parentY != y)                  {                     if(y == parentY - 1)                     {                        if(x == parentX - 1)                        {                           if((tiles[x + 1][y].tile == 1) || (tiles[x][y + 1].tile == 1))                              continue;                        }                                                if(x == parentX + 1)                        {                           if((tiles[x - 1][y].tile == 1) || (tiles[x][y + 1].tile == 1))                              continue;                        }                     } else if(y == parentY + 1)                     {                        if(x == parentX - 1)                        {                           if((tiles[x + 1][y].tile == 1) || (tiles[x][y - 1].tile == 1))                              continue;                        }                                                if(x == parentX + 1)                        {                           if((tiles[x - 1][y].tile == 1) || (tiles[x][y - 1].tile == 1))                              continue;                        }                     }                  }                                    origGCost = tiles[x][y].g;                                    if(!(tileDir % 2) || parentY == y)                  {                     tempGCost = 10 + addedGCost;                  } else                  {                     tempGCost = 14 + addedGCost;                  }                                    pathG += tempGCost;                  if(origGCost < pathG)                  {                     betterPath = &tiles[x][y];                     betterPathX = x;                     betterPathY = y;                  }                                    pathG = origPathG;               }                              tileDir = 0;            }                        if(betterPath != NULL)            {               AddToClosedList(&tiles[parentX][parentY]);               parentX = betterPathX;               parentY = betterPathY;            }                        drawMap();         }                  drawMap();      }            void FindPath()      {         CalculateTiles();      }            void drawMap()      {         system("cls");                  for(int y = 0; y < height; y++)         {            for(int x = 0; x < width; x++)            {               if(x == parentX && y == parentY)                  printf("PL ");                else if(targetX == x && targetY == y)                  printf("*  ");               else                  printf("%d  ", tiles[x][y].tile);            }                        printf("\n");         }      }            bool FoundTarget()      {         if(parentX == targetX && parentY == targetY)            return true;                  return false;      }            bool onOpenList(cTile* pTile)      {         for(std::list<cTile*>::iterator iter = openList.begin();  iter != openList.end();            iter++)         {            if((*iter) == pTile)               return true;         }                  return false;      }            bool onClosedList(cTile* pTile)      {         for(std::list<cTile*>::iterator iter = closedList.begin();  iter != closedList.end();            iter++)         {            if((*iter) == pTile)               return true;         }                  return false;      }            void AddToOpenList(cTile* pTile)      {         if(!onOpenList(pTile))            openList.push_back(pTile);         if(onClosedList(pTile))            closedList.remove(pTile);      }            void AddToClosedList(cTile* pTile)      {         if(!onClosedList(pTile))            closedList.push_back(pTile);         if(onOpenList(pTile))            openList.remove(pTile);      }            cMap(char* mapLoc)      {         std::ifstream ioData(mapLoc);                  ioData >> width >> height;                  tiles = new cTile*[width];         oldG = new cTile*[width];                  for(int j = 0; j < width; j++)   tiles[j] = new cTile[height];         for(int j = 0; j < width; j++)   oldG[j] = new cTile[height];                  for(int y = 0; y < height; y++)         {            for(int x = 0; x < width; x++)            {               ioData >> tiles[x][y].tile;                              if(tiles[x][y].tile == 2)               {                  parentX = x;                  parentY = y;                                    tiles[x][y].tile = 0;                  parentSquare = &tiles[x][y];                  AddToOpenList(&tiles[x][y]);                                 } else if(tiles[x][y].tile == 3)               {                  targetX = x;                  targetY = y;                                    tiles[x][y].tile = 0;                  AddToOpenList(&tiles[x][y]);               } else if(tiles[x][y].tile == 1)               {                  AddToClosedList(&tiles[x][y]);               }            }         }                  ioData.close();      }         private:            int width, height;      int parentX, parentY, targetX, targetY;            cTile** tiles;      cTile** oldG;      cTile* parentSquare;            std::list<cTile*> openList;      std::list<cTile*> closedList;};int main(int argc, char **argv){   cMap map("map.txt");   map.FindPath();         printf("\n\n");   system("PAUSE");   return 0;}
Hey babe.

This topic is closed to new replies.

Advertisement