一个明星c ++,有什么不对

时间:2012-02-06 13:40:31

标签: c++ path-finding a-star

在这里,我不知道为什么它不起作用。有时它确定,有时会崩溃,有时它会以错误的方式返回......

// apath.h

#ifndef APATH_H
#define APATH_H
#include <vector>
#include <cmath>
#include <memory>
#include <allegro.h>

using namespace std;

double len(int x1, int y1, int x2, int y2);

class GameMap;

class point
{
public:
      int x,y;
      double f,g;
      point *parent;
      point(int _x=0, int _y=0, point *par=NULL) {x=_x; y=_y; parent=par; f=0; g=0;};
      void countF(int sx, int sy, int tx, int ty)
      {
      g=len(x,y,tx,ty);
      f=g+len(sx,sy,x,y);
      };
};

struct point2d
{
      int x,y;
};

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const point2d directions[]=
{
      {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},
};


class path
{
public:
      vector<point2d> way;
      int step;
      bool findPath(int x, int y, int fx, int fy, GameMap& map, BITMAP* out);
private:
      vector<point> open;
      vector<point> closed;
};


#endif

和apath.cpp:

// apath.cpp

#include "apath.h"
#include <vector>
#include <cmath>



double len(int x1, int y1, int x2, int y2) 
{
       return (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
       //return max(abs(x1-x2), abs(y1-y2));

      /*int mx=max(x1,x2)-min(x1,x2);
      int my=max(y1,y2)-min(y1,y2);
      return (min(mx,my)*14+max(mx,my)-min(mx,my)*10);*/
};

bool findPoint(vector<point> arr, point pt, point &ret)
{
     for (int i=0; i<arr.size(); i++) if (arr[i].x==pt.x && arr[i].y==pt.y) { ret=arr[i]; return true;}
     return '\0';
};

// GameMap持有地图......

bool path::findPath(int x, int y, int fx, int fy, GameMap& map, BITMAP* out)
{
     while(!open.empty()) open.pop_back();
     while(!closed.empty()) closed.pop_back();
     while(!way.empty()) way.pop_back();

     point start(x,y);
     start.countF(x,y,fx,fy);
     open.push_back(start);

     point finish(fx,fy);

     double min=999999999;
     int index;
     point tmp;
     point *tmp2;
     point comparer;


     while (!findPoint(closed,finish,comparer))
     {
           min=999999999;
           for (int i=0; i<open.size(); i++)
           {
               if(open[i].f<min)
                   {
                       min=open[i].f;
                       index=i;
                   }
           }

           tmp=open[index];
           closed.push_back(open[index]);
           open.erase(open.begin()+index);

           for (int i=0; i<8; i++)
               {
                    tmp2=new point(tmp.x+directions[i].x,tmp.y+directions[i].y);
                    if (map.getCollisionXY(tmp2->x,tmp2->y)==1 // map.getCollision returns 1 when you cant pass through the tile and 0 otherwise...
                    || findPoint(closed,*tmp2,comparer)) continue;
                    if (!findPoint(open,*tmp2,comparer)) 
                    { 
                        point newP(tmp.x+directions[i].x,tmp.y+directions[i].y,&closed[closed.size()-1]);
                        newP.countF(x,y,fx,fy);
                        open.push_back(newP);
                    }
                    else
                    {
                        if (comparer.g>tmp.g)
                        {
                             comparer.parent=&closed[closed.size()-1];
                             comparer.countF(x,y,fx,fy);
                        }
                    }
                    delete tmp2;
               }
/*     for (int i=0; i<open.size(); i++)
        if (open[i].parent!=0)circlefill(out,open[i].x*16+4,open[i].y*16+4,3,0xff0000);
           if (open.empty()) return false;
     for (int i=0; i<closed.size(); i++)
        if (closed[i].parent!=0)circlefill(out,closed[i].x*16+12,closed[i].y*16+12,3,0xffff00);*/ //debug draw

     }
     point2d pt;
     pt.x=finish.x;
     pt.y=finish.y;
     way.push_back(pt);
     point wayer;
     wayer=closed[closed.size()-1];
     while(wayer.parent!=0) //CRASH from here
     {
         wayer=*wayer.parent;
         pt.x=wayer.x;
         pt.y=wayer.y;
         way.push_back(pt);
//         circlefill(out,pt.x*16+12,pt.y*16+12,3,0xffffff); //debug draw
     }    //CRASH to here, i dont exacly know where it is, but when trying to recreate path.
     return true;
};

一些解释: GameMap是带地图的类 并且它的getCollisionXY返回1,你不能通过tile,否则返回0。

Thanx寻求帮助。

1 个答案:

答案 0 :(得分:1)

我发现可能导致访问冲突的一个主要来源是您的点包含父项作为指针,它们是向量的成员。如果向量被重新分配,这些指针可能会失效。

除此之外,很难立即看到导致坠机的原因。

您真的应该通过调试器运行代码。我刚刚指出了一件我马上就会看到的事情。