#pragma warning (disable:4786) #include #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 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 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;iLeft (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;iRenderData (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=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;zGetOneCost (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;zGetOneCost (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 (m_LeftSplit?m_Top:m_Left)); return mid; } bool CMapNode::CalcPath (std::stack *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;ix][temp->y]; for (i=0;ix; 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= 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;ix][temp->y]; for (i=0;ix; 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= 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