Exemplo n.º 1
0
MapPath Map::pathfind( Vector2d start, Vector2d goal ){
	set< pair < float , Vector2d > > open;

	Tile& start_tile = (*this)[ start ];
	start_tile.position = start;
	start_tile.g_score = 0;
	start_tile.h_score = h_score( start_tile, goal );
	start_tile.f_score = start_tile.h_score;

	open.insert( make_pair( (*this)[ start ].f_score, start ) );
	size_t icount = 0;
	  
	while( !open.empty() ) {
		if( icount++ > 100 ) 	break;

		Tile& current = (*this)[ open.begin()->second ]; 
		open.erase( open.begin() );
		current.closed = true;

		if( current.position == goal ) 		break;
		if( current.status().is_blocked() ) 	continue;

		Vector2d diffs[] = { Vector2d(1,0), Vector2d(-1,0), Vector2d(0,1), Vector2d(0,-1) };
		for( int i = 0; i < sizeof(diffs)/sizeof(Vector2d); ++i ) {
			Vector2d new_position = current.position + diffs[i];
			Tile& new_tile = (*this)[ new_position ];

			if( new_tile.closed ) continue;

			float new_g = current.g_score + 1;
			bool better_g = false;

			if( new_tile.g_score < 0 ){
				new_tile.h_score = h_score( (*this)[ new_position ], goal );
				better_g = true;

			} else if( new_g < new_tile.g_score ) {
				open.erase( make_pair( new_tile.f_score, new_position ) );
				better_g = true;
			}

			if( better_g ) {
				new_tile.g_score = new_g;
				new_tile.f_score = new_tile.h_score + new_tile.g_score;
				new_tile.origin = current.position;
				open.insert( make_pair( new_tile.f_score, new_position ) );
			}
		}
	}

	MapPath path;
	Vector2d pos = goal;

	while( pos != start ) {
		path.push_back( pos );
		pos = (*this)[ pos ].origin;
	}

	return path;
}
Exemplo n.º 2
0
bool PathFinder::makeMap(const Coord& start, Heuristic heur, EndCondition endCondition, Coord* end)
{
  m_openSet.clear();
  m_closedSet.clear();
  std::priority_queue<DistNode> openQueue;
  g_score(start) = 0;
  h_score(start) = heur(start);

  openQueue.push( DistNode( start, h_score(start) ) );
  m_openSet.add(start);

  while ( !openQueue.empty() )
  {
    DistNode dn = openQueue.top();
    Coord c = dn.coord;
    openQueue.pop();
    if (g_score(c) + h_score(c) == dn.f_score)
    {
      // this entry in the queue is valid
      assert(!m_closedSet.has(c));
      if (endCondition(c))
      {
        *end = c;
        return true;
      }
      m_openSet.remove(c); 
      m_closedSet.add(c);
      unsigned int currentGScore = g_score(c);
      for (int dir = 0; dir < 8; ++dir)
      {
        Coord next = c.next(dir);
        if (m_closedSet.has(next) || !m_field.isPassable(next))
        {
          continue;
        }
        unsigned int newG = currentGScore + m_field.passingTime(c, dir);
        bool newNode = false;
        if (!m_openSet.has(next))
        {
          h_score(next) = heur(next);
          m_openSet.add(next);
          newNode = true;
        }
        if (newNode || newG < g_score(next))
        {
          g_score(next) = newG;
          openQueue.push(DistNode(next, newG + h_score(next))); // may occur more than once, because we cannot remove the old one
        }
      }
    }
  }
  return false;
}