Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
868 lines
16 KiB
C++
868 lines
16 KiB
C++
#pragma warning (disable:4786)
|
|
#include <utils\utils.h>
|
|
#include "map.hpp"
|
|
#include "move.hpp"
|
|
|
|
MAPELEMENT g_Map[MAPSIZE][MAPSIZE];
|
|
|
|
void GenMap (MAPELEMENT map[MAPSIZE][MAPSIZE],int x1,int y1,int x2,int y2);
|
|
|
|
void InitMap (void)
|
|
{
|
|
int x,y;
|
|
|
|
for (y=0;y<MAPSIZE;y++)
|
|
for (x=0;x<MAPSIZE;x++)
|
|
{
|
|
g_Map[x][y].passable = true;
|
|
g_Map[x][y].weight = 0.0;
|
|
}
|
|
for (y=0;y<MAPSIZE;y++)
|
|
{
|
|
g_Map[0][y].passable = false;
|
|
g_Map[MAPSIZE-1][y].passable = false;
|
|
}
|
|
for (x=0;x<MAPSIZE;x++)
|
|
{
|
|
g_Map[x][0].passable = false;
|
|
g_Map[x][MAPSIZE-1].passable = false;
|
|
}
|
|
|
|
|
|
g_Map[0][0].weight = 0.5f;
|
|
g_Map[MAPSIZE-1][0].weight = 0.5f;
|
|
g_Map[0][MAPSIZE-1].weight = 0.5f;
|
|
g_Map[MAPSIZE-1][MAPSIZE-1].weight = 0.5f;
|
|
|
|
GenMap (g_Map,0,0,MAPSIZE-1,MAPSIZE-1);
|
|
|
|
|
|
for (y=0;y<MAPSIZE;y++)
|
|
for (x=0;x<MAPSIZE;x++)
|
|
{
|
|
if (g_Map[x][y].weight > 0.75)
|
|
g_Map[x][y].passable = false;
|
|
g_Map[x][y].weight+=1.0;
|
|
g_Map[x][y].weight *= 5.0;
|
|
}
|
|
|
|
InitMoveData ();
|
|
}
|
|
|
|
void RenderEdges (CDIBSurface& dest,int dx)
|
|
{
|
|
int x,y;
|
|
|
|
for (y=0;y<MAPCELLCOUNT;y++)
|
|
for (x=0;x<MAPCELLCOUNT;x++)
|
|
{
|
|
g_MapCells[x][y].RenderEdges (dest,dx);
|
|
}
|
|
}
|
|
|
|
int SquareInfo (int x,int y)
|
|
{
|
|
return Passable (x,y);
|
|
}
|
|
|
|
void GenMap (MAPELEMENT map[MAPSIZE][MAPSIZE],int x1,int y1,int x2,int y2)
|
|
{
|
|
int midx,midy;
|
|
double v1,v2,v3,v4;
|
|
double rmax;
|
|
|
|
|
|
if (x2 <= x1)
|
|
return;
|
|
if (y2 <= y1)
|
|
return;
|
|
|
|
midx = (x1+x2)/2;
|
|
midy = (y1+y2)/2;
|
|
|
|
rmax = RAND_MAX;
|
|
if (map[midx][y1].weight == 0.0)
|
|
{
|
|
v1 = map[midx][y1].weight = ((map[x1][y1].weight + map[x2][y1].weight) / 2.0) + (((rand()/rmax)-0.5)*((x2-x1)/MAPX));
|
|
if (v1<0)
|
|
map[midx][y1].weight = 0;
|
|
if (v1 > 1.0)
|
|
map[midx][y1].weight = 1.0;
|
|
}
|
|
else v1 = map[midx][y1].weight;
|
|
|
|
if (map[midx][y2].weight ==0.0)
|
|
{
|
|
v2 = map[midx][y2].weight = ((map[x1][y2].weight + map[x2][y2].weight) / 2.0) + (((rand()/rmax)-0.5)*((x2-x1)/MAPX));
|
|
if (v2<0)
|
|
map[midx][y2].weight = 0;
|
|
if (v2 > 1.0)
|
|
map[midx][y2].weight = 1.0;
|
|
}
|
|
else v2 = map[midx][y2].weight;
|
|
|
|
if (map[x1][midy].weight == 0.0)
|
|
{
|
|
v3 = map[x1][midy].weight = ((map[x1][y1].weight + map[x1][y2].weight) / 2.0) + (((rand()/rmax)-0.5)*((y1-y2)/MAPY));
|
|
if (v3<0)
|
|
map[x1][midy].weight = 0;
|
|
if (v3 > 1.0)
|
|
map[x1][midy].weight = 1.0;
|
|
}
|
|
else v3 = map[x1][midy].weight;
|
|
|
|
if (map[x2][midy].weight == 0.0)
|
|
{
|
|
v4 = map[x2][midy].weight = ((map[x2][y1].weight + map[x2][y2].weight) / 2.0) + (((rand()/rmax)-0.5)*((y1-y2)/MAPY));
|
|
if (v4<0)
|
|
map[x2][midy].weight = 0;
|
|
if (v4 > 1.0)
|
|
map[x2][midy].weight = 1.0;
|
|
}
|
|
else v4 = map[x2][midy].weight;
|
|
|
|
|
|
if (map[midx][midy].weight == 0.0)
|
|
{
|
|
map[midx][midy].weight = ((v1+v2+v3+v4)/4.0) + 2*(((rand()/rmax)-0.5)*((y1-y2)/MAPY));
|
|
if (map[midx][midy].weight<0)
|
|
map[midx][midy].weight = 0;
|
|
if (map[midx][midy].weight > 1.0)
|
|
map[midx][midy].weight = 1.0;
|
|
}
|
|
/*
|
|
if (midx == x1)
|
|
return;
|
|
if (midx == x2)
|
|
return;
|
|
if (midy == y1)
|
|
return;
|
|
if (midy == y2)
|
|
return;
|
|
*/
|
|
if ((midx != x2) && (midx != x1))
|
|
{
|
|
GenMap (map,x1,y1,midx,midy);
|
|
GenMap (map,midx,y1,x2,midy);
|
|
}
|
|
if ((midy != y1) && (midy != y2))
|
|
{
|
|
GenMap (map,x1,midy,midx,y2);
|
|
GenMap (map,midx,midy,x2,y2);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
float GetOneCost (int sx,int sy,int dx,int dy)
|
|
{
|
|
int deltax,deltay;
|
|
float toret;
|
|
|
|
if (!Passable (dx,dy))
|
|
return -1;
|
|
|
|
toret = abs (g_Map[sx][sy].weight - g_Map[dx][dy].weight)+1;
|
|
// toret *= 0.5;
|
|
|
|
return toret;
|
|
deltax = dx - sx;
|
|
deltay = dy - sy;
|
|
if (deltax == 0)
|
|
return toret*0.5;
|
|
if (deltay == 0)
|
|
return toret*0.5;
|
|
return toret * 0.75;
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
CMapNode::CMapNode (void)
|
|
{
|
|
m_Left = NULL;
|
|
m_Right = NULL;
|
|
m_Bottom = NULL;
|
|
m_Top = NULL;
|
|
|
|
int i;
|
|
|
|
for (i=0;i<PASS_NUM;i++)
|
|
{
|
|
m_Passable[i] = true;
|
|
}
|
|
|
|
m_PassAverage = 0;
|
|
m_WeightAverage = 0;
|
|
|
|
m_MapQuad = NULL;
|
|
m_MapQuad = new CMapQuadNode (NULL,this);
|
|
m_MapQuad->Left (0);
|
|
m_MapQuad->Top (0);
|
|
m_MapQuad->Right (MAPSIZE-1);
|
|
m_MapQuad->Bottom (MAPSIZE-1);
|
|
m_MapQuad->SubDivide ();
|
|
}
|
|
|
|
CMapNode::~CMapNode (void)
|
|
{
|
|
delete m_Left;
|
|
delete m_Right;
|
|
delete m_Bottom;
|
|
delete m_Top;
|
|
}
|
|
|
|
void CMapNode::RenderData (CDIBSurface& dest,int dx)
|
|
{
|
|
m_MapQuad->RenderData (dest,dx);
|
|
}
|
|
|
|
void CMapNode::RenderEdges (CDIBSurface& dest,int dx)
|
|
{
|
|
m_MapQuad->RenderEdges (dest,dx);
|
|
}
|
|
|
|
CMapQuadNode::CMapQuadNode (CMapQuadNode *parent,CMapNode *root)
|
|
{
|
|
m_Root = root;
|
|
m_Parent = parent;
|
|
m_Left = m_Right = m_Bottom = m_Top = 0;
|
|
m_Child[0] = NULL;
|
|
m_Child[1] = NULL;
|
|
m_Child[2] = NULL;
|
|
m_Child[3] = NULL;
|
|
|
|
int i;
|
|
|
|
for (i=0;i<PASS_NUM;i++)
|
|
{
|
|
m_Passable[i] = true;
|
|
}
|
|
|
|
m_PassAverage = 0;
|
|
m_WeightAverage = 0;
|
|
}
|
|
|
|
CMapQuadNode::~CMapQuadNode (void)
|
|
{
|
|
}
|
|
|
|
void CMapQuadNode::RenderData (CDIBSurface& dest,int dx)
|
|
{
|
|
const int CELLSIZE=2;
|
|
|
|
if (m_Child[0])
|
|
{
|
|
m_Child[0]->RenderData (dest,dx);
|
|
m_Child[1]->RenderData (dest,dx);
|
|
m_Child[2]->RenderData (dest,dx);
|
|
m_Child[3]->RenderData (dest,dx);
|
|
}
|
|
else
|
|
{
|
|
int color = 255.0 * ((m_WeightAverage/5.0)-1.0);
|
|
dest.Fill (dx+m_Left*CELLSIZE,m_Top*CELLSIZE,dx+(m_Right+1)*CELLSIZE,(m_Bottom+1)*CELLSIZE,RGB (color,color,color));
|
|
}
|
|
}
|
|
|
|
void CMapQuadNode::RenderEdges (CDIBSurface& dest,int dx)
|
|
{
|
|
const int CELLSIZE=2;
|
|
|
|
if (m_Child[0])
|
|
{
|
|
m_Child[0]->RenderEdges (dest,dx);
|
|
m_Child[1]->RenderEdges (dest,dx);
|
|
m_Child[2]->RenderEdges (dest,dx);
|
|
m_Child[3]->RenderEdges (dest,dx);
|
|
}
|
|
else
|
|
{
|
|
int x,y;
|
|
|
|
for (x=m_Left;x<m_Right;x++)
|
|
{
|
|
dest.Fill (dx+x*CELLSIZE,m_Top*CELLSIZE,dx+(x+1)*CELLSIZE,(m_Top+1)*CELLSIZE,RGB (0,255,0));
|
|
// dest.Fill (x*CELLSIZE,m_Bottom*CELLSIZE,(x+1)*CELLSIZE,(m_Bottom+1)*CELLSIZE,RGB (0,255,0));
|
|
}
|
|
for (y=m_Top;y<m_Bottom;y++)
|
|
{
|
|
dest.Fill (dx+m_Left*CELLSIZE,y*CELLSIZE,dx+(m_Left+1)*CELLSIZE,(y+1)*CELLSIZE,RGB (0,255,0));
|
|
// dest.Fill (m_Right*CELLSIZE,y*CELLSIZE,(m_Right+1)*CELLSIZE,(y+1)*CELLSIZE,RGB (0,255,0));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CMapQuadNode::SubDivide (void)
|
|
{
|
|
int midx,midy,count;
|
|
bool flag;
|
|
|
|
flag = true;
|
|
if ((m_Right-m_Left)<=MAXDEPTH)
|
|
flag = false;
|
|
if ((m_Bottom-m_Top)<=MAXDEPTH)
|
|
flag = false;
|
|
|
|
assert (m_Left>=0);
|
|
assert (m_Top>=0);
|
|
assert (m_Right <=MAPSIZE);
|
|
assert (m_Bottom <= MAPSIZE);
|
|
assert (m_Left < m_Right);
|
|
assert (m_Bottom > m_Top);
|
|
|
|
midy = (m_Bottom-m_Top+1)/2;
|
|
midx = (m_Right-m_Left+1)/2;
|
|
if (flag)
|
|
{
|
|
m_Child[0] = new CMapQuadNode (this,m_Root);
|
|
m_Child[1] = new CMapQuadNode (this,m_Root);
|
|
m_Child[2] = new CMapQuadNode (this,m_Root);
|
|
m_Child[3] = new CMapQuadNode (this,m_Root);
|
|
|
|
m_Child[TOPLEFT_CHILD]->SetSize (m_Left,m_Top,m_Left+midx,m_Top+midy);
|
|
m_Child[BOTTOMLEFT_CHILD]->SetSize (m_Left,m_Top+midy+1,m_Left+midx,m_Bottom);
|
|
m_Child[TOPRIGHT_CHILD]->SetSize (m_Left+midx+1,m_Top,m_Right,m_Top+midy);
|
|
m_Child[BOTTOMRIGHT_CHILD]->SetSize (m_Left+midx+1,m_Top+midy+1,m_Right,m_Bottom);
|
|
|
|
|
|
m_Child[0]->SubDivide ();
|
|
m_Child[1]->SubDivide ();
|
|
m_Child[2]->SubDivide ();
|
|
m_Child[3]->SubDivide ();
|
|
}
|
|
else
|
|
{
|
|
m_Child[0] = NULL;
|
|
m_Child[1] = NULL;
|
|
m_Child[2] = NULL;
|
|
m_Child[3] = NULL;
|
|
}
|
|
|
|
|
|
m_PassAverage = 0;
|
|
m_WeightAverage = 0;
|
|
count = 0;
|
|
for (midx = m_Left;midx<=m_Right;midx++)
|
|
{
|
|
for (midy=m_Top;midy<=m_Bottom;midy++)
|
|
{
|
|
count++;
|
|
m_WeightAverage+=g_Map[midx][midy].weight;
|
|
if (g_Map[midx][midy].passable)
|
|
{
|
|
m_PassAverage++;
|
|
}
|
|
}
|
|
}
|
|
m_PassAverage /= count;
|
|
m_WeightAverage /= count;
|
|
|
|
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
#if 0
|
|
double CMapQuadNode::CalcAverageCostSplit (int where,bool left )
|
|
{
|
|
int x,y,z;
|
|
int lx,hx,ly,hy;
|
|
double current;
|
|
int count;
|
|
|
|
assert (where < (m_LeftSplit?m_Bottom:m_Right));
|
|
assert (where > (m_LeftSplit?m_Top:m_Left));
|
|
assert (m_Left>=0);
|
|
assert (m_Top>=0);
|
|
assert (m_Right <=MAPSIZE);
|
|
assert (m_Bottom <= MAPSIZE);
|
|
assert (m_Left < m_Right);
|
|
assert (m_Bottom > m_Top);
|
|
if (m_LeftSplit)
|
|
{
|
|
lx = m_Left;
|
|
hx = m_Right;
|
|
if (left)
|
|
{
|
|
ly = m_Top;
|
|
hy = m_Top+where;
|
|
}
|
|
else
|
|
{
|
|
ly = m_Top+where+1;
|
|
hy = m_Bottom;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ly = m_Top;
|
|
hy = m_Bottom;
|
|
if (left)
|
|
{
|
|
lx = m_Left;
|
|
hx = m_Left+where;
|
|
}
|
|
else
|
|
{
|
|
lx = m_Left+where+1;
|
|
hx = m_Right;
|
|
}
|
|
}
|
|
count = 0;
|
|
current = 0.0;
|
|
for (x=lx;x<=hx;x++)
|
|
{
|
|
for (y=ly;y<=hy;y++)
|
|
{
|
|
for (z=0;z<OFFSIZE;z++)
|
|
{
|
|
double cost;
|
|
|
|
cost = g_MapTree->GetOneCost (x,y,x+offset[z][0],y+offset[z][1]);
|
|
if (cost < 0)
|
|
cost = 10000.0;
|
|
current+=cost;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
return current / ((double)count);
|
|
}
|
|
|
|
double CMapQuadNode::AnalyzeSplit (int where,bool left)
|
|
{
|
|
double average;
|
|
int x,y,z;
|
|
int lx,hx,ly,hy;
|
|
double current;
|
|
int count;
|
|
|
|
assert (where < (m_LeftSplit?m_Bottom:m_Right));
|
|
assert (where > (m_LeftSplit?m_Top:m_Left));
|
|
|
|
assert (m_Left>=0);
|
|
assert (m_Top>=0);
|
|
assert (m_Right <=MAPSIZE);
|
|
assert (m_Bottom <= MAPSIZE);
|
|
assert (m_Left < m_Right);
|
|
assert (m_Bottom > m_Top);
|
|
|
|
average = CalcAverageCostSplit (where,left);
|
|
|
|
if (m_LeftSplit)
|
|
{
|
|
lx = m_Left;
|
|
hx = m_Right;
|
|
if (left)
|
|
{
|
|
ly = m_Top;
|
|
hy = m_Top+where;
|
|
}
|
|
else
|
|
{
|
|
ly = m_Top+where+1;
|
|
hy = m_Bottom;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ly = m_Top;
|
|
hy = m_Bottom;
|
|
if (left)
|
|
{
|
|
lx = m_Left;
|
|
hx = m_Left+where;
|
|
}
|
|
else
|
|
{
|
|
lx = m_Left+where+1;
|
|
hx = m_Right;
|
|
}
|
|
}
|
|
count = 0;
|
|
current = 0.0;
|
|
for (x=lx;x<=hx;x++)
|
|
{
|
|
for (y=ly;y<=hy;y++)
|
|
{
|
|
for (z=0;z<OFFSIZE;z++)
|
|
{
|
|
double cost = g_MapTree->GetOneCost (x,y,x+offset[z][0],y+offset[z][1]);
|
|
if (cost < 0)
|
|
cost = 10000.0;
|
|
|
|
current+= ((cost-average) * (cost-average));
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
return current / ((double)count);
|
|
}
|
|
|
|
int CMapQuadNode::ChooseSplit (void)
|
|
{
|
|
int mid,min;
|
|
double minvalue;
|
|
double temp;
|
|
double splits[MAPSIZE][2];
|
|
double cost[MAPSIZE];
|
|
|
|
assert (m_Left>=0);
|
|
assert (m_Top>=0);
|
|
assert (m_Right <=MAPSIZE);
|
|
assert (m_Bottom <= MAPSIZE);
|
|
assert (m_Left < m_Right);
|
|
assert (m_Bottom > m_Top);
|
|
|
|
for (mid = 0;mid<MAPSIZE;mid++)
|
|
{
|
|
splits[mid][0] = 0.0;
|
|
splits[mid][1] = 0.0;
|
|
}
|
|
|
|
min = -1;
|
|
minvalue = DBL_MAX;
|
|
if (m_LeftSplit)
|
|
{
|
|
for (mid = (m_Top+MAXDEPTH4);mid<=(m_Bottom-MAXDEPTH4);mid++)
|
|
{
|
|
splits[mid][0] = AnalyzeSplit (mid,0);
|
|
splits[mid][1] = AnalyzeSplit (mid,1);
|
|
cost[mid] = splits[mid][0] + splits[mid][1];
|
|
temp = ((double)(mid-m_Top)/(double) (m_Bottom - m_Top));
|
|
temp *= PI;
|
|
// temp -= (PI/2.0);
|
|
temp = sin(temp);
|
|
temp = 1.0 - temp;
|
|
cost[mid] *= temp;
|
|
if (cost[mid] < minvalue)
|
|
{
|
|
min = mid;
|
|
minvalue = cost[mid];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (mid = (m_Left+MAXDEPTH4);mid<=(m_Right-MAXDEPTH4);mid++)
|
|
{
|
|
splits[mid][0] = AnalyzeSplit (mid,0);
|
|
splits[mid][1] = AnalyzeSplit (mid,1);
|
|
cost[mid] = splits[mid][0] + splits[mid][1];
|
|
temp = ((double)(mid-m_Left)/(double) (m_Right - m_Left));
|
|
temp *= PI;
|
|
// temp -= (PI/2.0);
|
|
temp = sin(temp);
|
|
temp = 1.0 - temp;
|
|
cost[mid] *= temp;
|
|
|
|
// temp = (((mid-m_Left)/(m_Right - m_Left)) * PI)-(PI/2.0);
|
|
// temp = 1.0 - sin (temp);
|
|
cost[mid] *= temp;
|
|
if (cost[mid] < minvalue)
|
|
{
|
|
min = mid;
|
|
minvalue = cost[mid];
|
|
}
|
|
}
|
|
}
|
|
if (min < 0)
|
|
{
|
|
if (m_LeftSplit)
|
|
mid = (m_Bottom-m_Top+1)/2;
|
|
else
|
|
mid = (m_Right-m_Left+1)/2;
|
|
}
|
|
else
|
|
mid = min;
|
|
|
|
assert (mid < (m_LeftSplit?m_Bottom:m_Right));
|
|
assert (mid > (m_LeftSplit?m_Top:m_Left));
|
|
|
|
return mid;
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CMapNode::CalcPath (std::stack<PATHELEMENT> *dest,CPoint start,CPoint end,int depth,bool followshort)
|
|
{
|
|
int i,j;
|
|
FibHeap calc;
|
|
CALCELEMENT *temp;
|
|
CALCELEMENT *shortdes = NULL;
|
|
int lastdepth;
|
|
|
|
int x=-1,y=-1;
|
|
bool done;
|
|
|
|
while (!dest->empty ())
|
|
dest->pop ();
|
|
|
|
for (i=0;i<MAPSIZE;i++)
|
|
{
|
|
for (j=0;j<MAPSIZE;j++)
|
|
{
|
|
pathmap[i][j] = 0;
|
|
}
|
|
}
|
|
|
|
temp = new CALCELEMENT (start.x,start.y);
|
|
pathmap[start.x][start.y] = 1;
|
|
calc.Insert (temp);
|
|
|
|
done = false;
|
|
lastdepth = 0;
|
|
while (!done && ((depth == -1)||(depth<lastdepth)))
|
|
{
|
|
temp = (CALCELEMENT *) calc.ExtractMin ();
|
|
if (temp == NULL)
|
|
break;
|
|
lastdepth = pathmap[temp->x][temp->y];
|
|
for (i=0;i<OFFSIZE;i++)
|
|
{
|
|
x = offset[i][0] + temp->x;
|
|
y = offset[i][1] + temp->y;
|
|
float cost = GetOneCost (temp->x,temp->y,x,y);
|
|
if (cost == -1)
|
|
continue;
|
|
cost += PathCostGuess (x,y,end.x,end.y);
|
|
if ((pathmap[x][y] == 0) || (pathmap[x][y] > (pathmap[temp->x][temp->y]+cost)))
|
|
{
|
|
pathmap[x][y] = pathmap[temp->x][temp->y]+cost;
|
|
calc.Insert (new CALCELEMENT(x,y));
|
|
}
|
|
if ((x == end.x) && (y == end.y))
|
|
{
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
delete temp;
|
|
}
|
|
if ((!done) && (depth != -1) && (depth>=lastdepth) && followshort)
|
|
{
|
|
shortdes = (CALCELEMENT *) calc.ExtractMin ();
|
|
if (shortdes)
|
|
done = true;
|
|
}
|
|
|
|
while (temp = (CALCELEMENT *) calc.ExtractMin ())
|
|
delete temp;
|
|
|
|
if (!done)
|
|
return false;
|
|
|
|
done = false;
|
|
int curx,cury,min;
|
|
|
|
if (shortdes)
|
|
{
|
|
curx = shortdes->x;
|
|
cury = shortdes->y;
|
|
delete shortdes;
|
|
}
|
|
else
|
|
{
|
|
curx = end.x;
|
|
cury = end.y;
|
|
}
|
|
dest->push (PATHELEMENT (curx,cury));
|
|
min = -1;
|
|
while (!done)
|
|
{
|
|
min = -1;
|
|
assert (pathmap[curx][cury] != 0);
|
|
for (i=0;i<OFFSIZE;i++)
|
|
{
|
|
x = offset[i][0] + curx;
|
|
y = offset[i][1] + cury;
|
|
if (x < 0)
|
|
continue;
|
|
if (x >= MAPSIZE)
|
|
continue;
|
|
if (y < 0)
|
|
continue;
|
|
if (y >= MAPSIZE)
|
|
continue;
|
|
if (pathmap[x][y] == 0)
|
|
continue;
|
|
if (pathmap[x][y] < pathmap[curx][cury])
|
|
{
|
|
if (min == -1)
|
|
min = i;
|
|
else
|
|
{
|
|
if (pathmap[x][y] < pathmap[curx+offset[min][0]][cury+offset[min][1]])
|
|
min = i;
|
|
}
|
|
}
|
|
}
|
|
assert (min != -1);
|
|
dest->push (PATHELEMENT (curx+offset[min][0],cury+offset[min][1]));
|
|
if (((curx+offset[min][0]) == start.x) && ((cury+offset[min][1]) == start.y))
|
|
{
|
|
done = true;
|
|
continue;
|
|
}
|
|
curx += offset[min][0];
|
|
cury += offset[min][1];
|
|
}
|
|
|
|
// m_CurPath.push (PATHELEMENT (curdes.x,curdes.y));
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
int i,j;
|
|
FibHeap calc;
|
|
CALCELEMENT *temp;
|
|
CALCELEMENT *shortdes = NULL;
|
|
int lastdepth;
|
|
|
|
int x=-1,y=-1;
|
|
bool done;
|
|
|
|
while (!dest->empty ())
|
|
dest->pop ();
|
|
|
|
for (i=0;i<MAPSIZE;i++)
|
|
{
|
|
for (j=0;j<MAPSIZE;j++)
|
|
{
|
|
pathmap[i][j] = 0;
|
|
}
|
|
}
|
|
|
|
temp = new CALCELEMENT (start.x,start.y);
|
|
pathmap[start.x][start.y] = 1;
|
|
calc.Insert (temp);
|
|
|
|
done = false;
|
|
lastdepth = 0;
|
|
while (!done && ((depth == -1)||(depth<lastdepth)))
|
|
{
|
|
temp = (CALCELEMENT *) calc.ExtractMin ();
|
|
if (temp == NULL)
|
|
break;
|
|
lastdepth = pathmap[temp->x][temp->y];
|
|
for (i=0;i<OFFSIZE;i++)
|
|
{
|
|
x = offset[i][0] + temp->x;
|
|
y = offset[i][1] + temp->y;
|
|
float cost = GetOneCost (temp->x,temp->y,x,y);
|
|
if (cost == -1)
|
|
continue;
|
|
cost += PathCostGuess (x,y,end.x,end.y);
|
|
if ((pathmap[x][y] == 0) || (pathmap[x][y] > (pathmap[temp->x][temp->y]+cost)))
|
|
{
|
|
pathmap[x][y] = pathmap[temp->x][temp->y]+cost;
|
|
calc.Insert (new CALCELEMENT(x,y));
|
|
}
|
|
if ((x == end.x) && (y == end.y))
|
|
{
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
delete temp;
|
|
}
|
|
if ((!done) && (depth != -1) && (depth>=lastdepth) && followshort)
|
|
{
|
|
shortdes = (CALCELEMENT *) calc.ExtractMin ();
|
|
if (shortdes)
|
|
done = true;
|
|
}
|
|
|
|
while (temp = (CALCELEMENT *) calc.ExtractMin ())
|
|
delete temp;
|
|
|
|
if (!done)
|
|
return false;
|
|
|
|
done = false;
|
|
int curx,cury,min;
|
|
|
|
if (shortdes)
|
|
{
|
|
curx = shortdes->x;
|
|
cury = shortdes->y;
|
|
delete shortdes;
|
|
}
|
|
else
|
|
{
|
|
curx = end.x;
|
|
cury = end.y;
|
|
}
|
|
dest->push (PATHELEMENT (curx,cury));
|
|
min = -1;
|
|
while (!done)
|
|
{
|
|
min = -1;
|
|
assert (pathmap[curx][cury] != 0);
|
|
for (i=0;i<OFFSIZE;i++)
|
|
{
|
|
x = offset[i][0] + curx;
|
|
y = offset[i][1] + cury;
|
|
if (x < 0)
|
|
continue;
|
|
if (x >= MAPSIZE)
|
|
continue;
|
|
if (y < 0)
|
|
continue;
|
|
if (y >= MAPSIZE)
|
|
continue;
|
|
if (pathmap[x][y] == 0)
|
|
continue;
|
|
if (pathmap[x][y] < pathmap[curx][cury])
|
|
{
|
|
if (min == -1)
|
|
min = i;
|
|
else
|
|
{
|
|
if (pathmap[x][y] < pathmap[curx+offset[min][0]][cury+offset[min][1]])
|
|
min = i;
|
|
}
|
|
}
|
|
}
|
|
assert (min != -1);
|
|
dest->push (PATHELEMENT (curx+offset[min][0],cury+offset[min][1]));
|
|
if (((curx+offset[min][0]) == start.x) && ((cury+offset[min][1]) == start.y))
|
|
{
|
|
done = true;
|
|
continue;
|
|
}
|
|
curx += offset[min][0];
|
|
cury += offset[min][1];
|
|
}
|
|
|
|
// m_CurPath.push (PATHELEMENT (curdes.x,curdes.y));
|
|
return true;
|
|
#endif
|
|
|