PDA

View Full Version : Help with RTS book


daviangel
11-22-2006, 02:08 AM
Anyone else have this book and using VS2005 with the source code?

The reason I ask is that I'm having a hard time trying to get the code to compile under VS2005 since I think the source code was originally compiled under VC6 since the first error I ran into is the for loop variable not found error since the scope changes from VC6 to VC2005 but I easily fixed those.
Then I ran into strmiids.lib linker errors which I found out was due to missing directshow library files which aren't included with latest DX SDK(I'm using oct 06 version). I fixed that by downloading latest vista platform sdk which includes directshow stuff.
Anyways the final error that I need help with is a vector.erase error that I think needs a cast to work properly but I can't figure it out so I just commented it out for now the line in question is this:
open.erase(&open[bestPlace]); // Take the best node out of the Open list

more code in context below
Thanks for any help since there's nowhere else to turn...

code:

std::vector<INTPOINT> TERRAIN::GetPath(INTPOINT start, INTPOINT goal, bool considerUnits, MAPOBJECT *unit)
{
try
{
//Check that the two points are within the bounds of the map
MAPTILE *startTile = GetTile(start);
MAPTILE *goalTile = GetTile(goal);

if(!Within(start) || !Within(goal) || start == goal || startTile == NULL || goalTile == NULL)
return std::vector<INTPOINT>();

//Check if a path exists
if(!startTile->m_walkable || !goalTile->m_walkable || startTile->m_set != goalTile->m_set)
return std::vector<INTPOINT>();

//Check that goal tile isnt busy if considering units
if(considerUnits && goalTile->m_pMapObject != NULL)
goal = GetClosestFreeTile(goal, start);

if(H(start, goal) < 10 && considerUnits && !PositionAccessible(unit, goal))
return std::vector<INTPOINT>();

//Init Search
long numTiles = m_size.x * m_size.y;
for(long l=0;l<numTiles;l++)
{
m_pMapTiles[l].f = m_pMapTiles[l].g = INT_MAX; //Clear F,G
m_pMapTiles[l].open = m_pMapTiles[l].closed = false; //Reset Open and Closed
}

std::vector<MAPTILE*> open; //Create Our Open list
startTile->g = 0; //Init our starting point (SP)
startTile->f = H(start, goal);
startTile->open = true;
open.push_back(startTile); //Add SP to the Open list

bool found = false; // Search as long as a path hasnt been found,

while(!found && !open.empty()) // or there is no more tiles to search
{
MAPTILE * best = open[0]; // Find the best tile (i.e. the lowest F value)
int bestPlace = 0;
for(int i=1;i<open.size();i++)
if(open[i] != NULL && open[i]->f < best->f)
{
best = open[i];
bestPlace = i;
}

if(best == NULL)break; //No path found
if(considerUnits && open.size() > 100)break;

open[bestPlace]->open = false;
open.erase(&open[bestPlace]); // Take the best node out of the Open list

if(best->m_mappos == goal) //If the goal has been found
{
std::vector<INTPOINT> p, p2;
MAPTILE *point = best;

while(point->m_mappos != start && point != NULL) // Generate path
{
p.push_back(point->m_mappos);
point = point->m_pParent;

if(p.size() > 500) //Too long path, something is wrong
return std::vector<INTPOINT>();
}

for(int i=p.size()-1;i!=0;i--) // Reverse path
p2.push_back(p[i]);
p2.push_back(goal);

return p2;
}
else
{
for(int i=0;i<8;i++) // otherwise, check the neighbors of the
if(best->neighbors[i] != NULL) // best tile
if(!considerUnits || best->neighbors[i]->m_pMapObject == NULL)
{
bool inList = false; // Generate new G and F value
float newG = best->g + 1.0f;
float d = H(best->m_mappos, best->neighbors[i]->m_mappos);
float newF = newG + H(best->neighbors[i]->m_mappos, goal) + best->neighbors[i]->m_cost * 5.0f * d;

if(best->neighbors[i]->open || best->neighbors[i]->closed)
{
if(newF < best->neighbors[i]->f) // If the new F value is lower
{
best->neighbors[i]->g = newG; // update the values of this tile
best->neighbors[i]->f = newF;
best->neighbors[i]->m_pParent = best;
}
inList = true;
}

if(!inList) // If the neighbor tile isn't in the Open or Closed list
{
best->neighbors[i]->f = newF; //Set the values
best->neighbors[i]->g = newG;
best->neighbors[i]->m_pParent = best;
best->neighbors[i]->open = true;
open.push_back(best->neighbors[i]); //Add it to the open list
}
}

best->closed = true; //The best tile has now been searched, add it to the Closed list
}
}

return std::vector<INTPOINT>(); //No path found, return an empty path
}
catch(...)
{
debug.Print("Error in TERRAIN::GetPath()");
return std::vector<INTPOINT>();
}
}

dave_
11-22-2006, 04:03 AM
Thats an easy one.
operator [] returns a reference, erase takes an iterator. You need to do this: open.erase(open.begin()+bestPlace));

Iterators allow you to easily interchange container types, so perhaps you could use them instead of bestPlace and i

Next time I suggest you post the actual error message, and a bit less code. Perhaps try to reproduce it in a test application.