Jump to content


Help with RTS book


1 reply to this topic

#1 daviangel

    New Member

  • Members
  • PipPip
  • 15 posts

Posted 22 November 2006 - 10: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>();
	}
}


#2 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 22 November 2006 - 12:03 PM

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.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users