void BuildingPrefecture::deliverService()
{
  if( getWorkers() > 0 && getWalkerList().size() == 0 )
  {
    bool fireDetect = _fireDetect.getI() >= 0;
    WalkerPrefectPtr walker = WalkerPrefect::create( Scenario::instance().getCity() );
    walker->setMaxDistance( 26 );

    //bool patrol = true;
    if( fireDetect )
    {
      PathWay pathway;
      TilePos startPos = _accessRoads.front()->getIJ();
      bool pathFounded = Pathfinder::getInstance().getPath( startPos, _fireDetect, pathway, false, Size( 0 ) );
      //patrol = !pathFounded;

      if( pathFounded )
      {
        walker->setPathWay( pathway );
        walker->setIJ( pathway.getOrigin().getIJ() );
      }

      _fireDetect = TilePos( -1, -1 );
    }
    
    walker->send2City( BuildingPrefecturePtr( this ), fireDetect ? 200 : 0 );

    addWalker( walker.as<Walker>() );
  }
}
Пример #2
0
float ServiceWalker::evaluatePath(PathWay &pathWay)
{
   // evaluate all buildings along the path
   std::set<Building*> doneBuildings;  // list of evaluated building: don't do them again
   std::list<Tile*>& pathTileList = pathWay.getAllTiles();

   int distance = 0;
   float res = 0.0;
   for (std::list<Tile*>::iterator itTile = pathTileList.begin(); itTile != pathTileList.end(); ++itTile)
   {
      Tile &tile = **itTile;
      std::set<Building*> reachedBuildings = getReachedBuildings(tile.getI(), tile.getJ());
      for (std::set<Building*>::iterator itBuilding = reachedBuildings.begin(); itBuilding != reachedBuildings.end(); ++itBuilding)
      {
         Building& building = **itBuilding;
         std::pair<std::set<Building*>::iterator, bool> rc = doneBuildings.insert(&building);
         if (rc.second == true)
         {
            // the building has not been evaluated yet
            res = res + building.evaluateService(*this);
         }
      }
      distance++;
   }

   // std::cout << "evaluate path ";
   // pathWay.prettyPrint();
   // std::cout << " = " << res << std::endl;

   return res;
}
Пример #3
0
void WalkerPrefect::_checkPath2NearestFire( const ReachedBuildings& buildings )
{
  PathWay bestPath;
  int minLength = 9999;
  foreach( BuildingPtr building, buildings )
  {
    if( building->getType() != B_BURNING_RUINS )
      continue;

    PathWay tmp;
    bool foundPath = Pathfinder::getInstance().getPath( getIJ(), building->getTile().getIJ(), tmp,
                                                        false, Size( 0 ) ); 
    if( foundPath && tmp.getLength() < minLength )
    {
      bestPath = tmp;
      minLength = tmp.getLength();
      
      if( tmp.getLength() == 1 )
        break;
    }
  }

  if( bestPath.getLength() > 0 )
  {
    setPathWay( bestPath );
    //_pathWay.begin();
  }
}
Пример #4
0
void WalkerPrefect::_checkPath2NearestFire( const ReachedBuildings& buildings )
{
  PathWay bestPath;
  int minLength = 9999;
  for( ReachedBuildings::const_iterator itBuilding = buildings.begin(); 
       itBuilding != buildings.end(); ++itBuilding)
  {
    if( (*itBuilding)->getType() != B_BURNING_RUINS )
      continue;

    PathWay tmp;
    bool foundPath = Pathfinder::getInstance().getPath( getIJ(), (*itBuilding)->getTile().getIJ(), tmp, 
                                                        false, Size( 0 ) ); 
    if( foundPath && tmp.getLength() < minLength )
    {
      bestPath = tmp;
      minLength = tmp.getLength();
      
      if( tmp.getLength() == 1 )
        break;
    }
  }

  if( bestPath.getLength() > 0 )
  {
    _pathWay = bestPath;
    _pathWay.begin();
  }
}
Пример #5
0
void ServiceWalker::reservePath(PathWay &pathWay)
{
   // reserve all buildings along the path
   std::set<Building*> doneBuildings;  // list of evaluated building: don't do them again
   std::list<Tile*>& pathTileList = pathWay.getAllTiles();

   for (std::list<Tile*>::iterator itTile = pathTileList.begin(); itTile != pathTileList.end(); ++itTile)
   {
      Tile &tile = **itTile;
      std::set<Building*> reachedBuildings = getReachedBuildings(tile.getI(), tile.getJ());
      for (std::set<Building*>::iterator itBuilding = reachedBuildings.begin(); itBuilding != reachedBuildings.end(); ++itBuilding)
      {
         Building &building = **itBuilding;
         std::pair<std::set<Building*>::iterator, bool> rc = doneBuildings.insert(&building);
         if (rc.second == true)
         {
            // the building has not been reserved yet
            building.reserveService(_service);
         }
      }
   }
}
Пример #6
0
bool Pathfinder::aStar( const TilePos& startPos, const TilePos& stopPos, 
                        const Size& arrivedArea, PathWay& oPathWay,
                        int flags )
{
  oPathWay.init( *_tilemap, _tilemap->at( startPos ) );

  // Define points to work with
  AStarPoint* start = getPoint( startPos );
  AStarPoint* end = getPoint( stopPos );
  AStarPoint* current;
  AStarPoint* child;

  // Define the open and the close list
  list<AStarPoint*> openList;
  list<AStarPoint*> closedList;
  list<AStarPoint*>::iterator i;

  int tSize = _tilemap->getSize();
  map<AStarPoint*,AStarPoint::WalkableType> saveArrivedArea;

  TilePos arrivedAreaStart( math::clamp( stopPos.getI()-arrivedArea.getWidth(), 0, tSize ),
                            math::clamp( stopPos.getJ()-arrivedArea.getHeight(), 0, tSize) );

  TilePos arrivedAreaStop(  math::clamp( stopPos.getI()+arrivedArea.getWidth(), 0, tSize ),
                            math::clamp( stopPos.getJ()+arrivedArea.getHeight(), 0, tSize) );
  
  for( int i=arrivedAreaStart.getI(); i <= arrivedAreaStop.getI(); i++ )
  {
    for( int j=arrivedAreaStart.getJ(); j <= arrivedAreaStop.getJ(); j++ )
    {
      AStarPoint* ap = getPoint( TilePos( i, j) );
      if( ap )
      {
        saveArrivedArea[ ap ] = ap->priorWalkable;
        ap->priorWalkable = AStarPoint::alwaysWalkable;
      }
    }
  }

  unsigned int n = 0;

  // Add the start point to the openList
  openList.push_back(start);
  start->opened = true;

  while (n == 0 || (current != end && n < getMaxLoopCount() ))
  {
    // Look for the smallest F value in the openList and make it the current point
    for (i = openList.begin(); i != openList.end(); ++ i)
    {
      if (i == openList.begin() || (*i)->getFScore() <= current->getFScore())
      {
        current = (*i);
      }
    }

    // Stop if we reached the end
    if( current == end ) 
    {
      break;
    }

    // Remove the current point from the openList
    openList.remove(current);
    current->opened = false;

    // Add the current point to the closedList
    closedList.push_back(current);
    current->closed = true;

    // Get all current's adjacent walkable points
    for (int x = -1; x < 2; x ++)
    {
      for (int y = -1; y < 2; y ++)
      {
        // If it's current point then pass
        if (x == 0 && y == 0)
        {
          continue;
        }

        // Get this point
        child = getPoint( current->getPos() + TilePos( x, y ) );

        // If it's closed or not walkable then pass
        if (child->closed || !child->isWalkable() )
        {
          continue;
        }

        // If we are at a corner
        if (x != 0 && y != 0)
        {
          // if the next horizontal point is not walkable or in the closed list then pass
          //AStarPoint* tmpPoint = getPoint( current->pos + TilePos( 0, y ) );
          TilePos tmp = current->getPos() + TilePos( 0, y );
          if( !pointIsWalkable( tmp ) || getPoint( tmp )->closed)
          {
            continue;
          }

          tmp = current->getPos() + TilePos( x, 0 );
          // if the next vertical point is not walkable or in the closed list then pass
          if( !pointIsWalkable( tmp ) || getPoint( tmp )->closed)
          {
            continue;
          }
        }

        // If it's already in the openList
        if (child->opened)
        {
          // If it has a wroste g score than the one that pass through the current point
          // then its path is improved when it's parent is the current point
          if (child->getGScore() > child->getGScore(current))
          {
            // Change its parent and g score
            child->setParent(current);
            child->computeScores(end);
          }
        }
        else
        {
          // Add it to the openList with current point as parent
          openList.push_back(child);
          child->opened = true;

          // Compute it's g, h and f score
          child->setParent(current);
          child->computeScores(end);
        }
      }
    }

    n++;
  }

  // Reset
  for (i = openList.begin(); i != openList.end(); ++ i)
  {
    (*i)->opened = false;
  }
  for (i = closedList.begin(); i != closedList.end(); ++ i)
  {
    (*i)->closed = false;
  }

  for( map<AStarPoint*,AStarPoint::WalkableType>::iterator it=saveArrivedArea.begin(); it != saveArrivedArea.end(); it++ )
  {
    it->first->priorWalkable = it->second;
  }

  if( n == getMaxLoopCount() )
  {
    return false;
  }
  // Resolve the path starting from the end point
  list<AStarPoint*> lPath;
  while( current->hasParent() && current != start )
  {
    lPath.push_front( current );
    current = current->getParent();
    n++;
  }

  for( list<AStarPoint*>::iterator lpIt=lPath.begin(); lpIt != lPath.end(); lpIt++ )
  {
    oPathWay.setNextTile( _tilemap->at( (*lpIt)->getPos() ) );
  }

  return oPathWay.getLength() > 0;
}