示例#1
0
 int getGScore(AStarPoint* p)
 { 
   int offset = p->tile->get_terrain().isRoad() ? -5 : +10;
   TilePos pos = tile ? tile->getIJ() : TilePos( 0, 0 ); 
   TilePos otherPos = p->tile->getIJ();
   return p->g + ((pos.getI() == otherPos.getI() || pos.getJ() == otherPos.getJ()) ? 10 : 14) + offset;
 }
示例#2
0
/* INCORRECT! */
bool Wharf::canBuild(const TilePos& pos ) const
{
  bool is_constructible = Construction::canBuild( pos );

  // We can build wharf only on straight border of water and land
  //
  //   ?WW? ???? ???? ????
  //   ?XX? WXX? ?XXW ?XX?
  //   ?XX? WXX? ?XXW ?XX?
  //   ???? ???? ???? ?WW?
  //

  bool bNorth = true;
  bool bSouth = true;
  bool bWest  = true;
  bool bEast  = true;
   
  Tilemap& tilemap = Scenario::instance().getCity().getTilemap();
   
  std::list<Tile*> rect = tilemap.getRectangle( pos + TilePos( -1, -1 ), Size( _size+2 ), false);
  for (std::list<Tile*>::iterator itTiles = rect.begin(); itTiles != rect.end(); ++itTiles)
  {
    Tile &tile = **itTiles;
    std::cout << tile.getI() << " " << tile.getJ() << "  " << pos.getI() << " " << pos.getJ() << std::endl;
      
     // if (tiles.get_terrain().isWater())
      
     if (tile.getJ() > (pos.getJ() + _size -1) && !tile.get_terrain().isWater()) {  bNorth = false; }
     if (tile.getJ() < pos.getJ() && !tile.get_terrain().isWater())              {  bSouth = false; }
     if (tile.getI() > (pos.getI() + _size -1) && !tile.get_terrain().isWater()) {  bEast = false;  }
     if (tile.getI() < pos.getI() && !tile.get_terrain().isWater())              {  bWest = false;  }      
   }

   return (is_constructible && (bNorth || bSouth || bEast || bWest));
}
示例#3
0
std::list<Tile*> Tilemap::getFilledRectangle(const TilePos& start, const TilePos& stop )
{
   std::list<Tile*> res;

   for (int i = start.getI(); i <= stop.getI(); ++i)
   {
      for (int j = start.getJ(); j <= stop.getJ(); ++j)
      {
         if( is_inside( TilePos( i, j ) ))
         {
            res.push_back(&at( TilePos( i, j ) ) );
         }
      }
   }

   return res;
}
示例#4
0
std::list<AStarPoint*> Pathfinder::getTraversingPoints( const TilePos& start, const TilePos& stop )
{
  std::list<AStarPoint*> points;

  if( start == stop )
    return points;

  points.push_back( getPoint( start ) );

  TilePos housePos = stop;               
  while( points.back()->getPos() != housePos )
  {
    TilePos ij = points.back()->getPos();
    TilePos move( math::clamp( housePos.getI() - ij.getI(), -1, 1 ), math::clamp( housePos.getJ() - ij.getJ(), -1, 1 ) );
    points.push_back( getPoint( ij + move ) );
  }

  return points;
}
示例#5
0
void GameLoader::Impl::initEntryExitTile( const TilePos& tlPos, Tilemap& tileMap, const unsigned int picIdStart, bool exit )
{
  unsigned int idOffset = 0;
  TilePos tlOffset;
  if( tlPos.getI() == 0 || tlPos.getI() == tileMap.getSize() - 1 )
  {
    tlOffset = TilePos( 0, 1 );
    idOffset = (tlPos.getI() == 0 ? 1 : 3 );

  }
  else if( tlPos.getJ() == 0 || tlPos.getJ() == tileMap.getSize() - 1 )
  {
    tlOffset = TilePos( 1, 0 );
    idOffset = (tlPos.getJ() == 0 ? 2 : 0 );
  }

  Tile& signTile = tileMap.at( tlPos + tlOffset );

  StringHelper::debug( 0xff, "(%d, %d)", tlPos.getI(),    tlPos.getJ()    );
  StringHelper::debug( 0xff, "(%d, %d)", tlOffset.getI(), tlOffset.getJ() );

  signTile.setPicture( ResourceGroup::land3a, picIdStart + idOffset );
  signTile.setFlag( Tile::tlRock, true );
}
bool RoadPropagator::getPath( const Tile& destination, ConstWayOnTiles& oPathWay ) const
{
  TilePos startPos = _d->startTile.getIJ();
  TilePos stopPos  = destination.getIJ();
  int iStep = (startPos.getI() < stopPos.getI()) ? 1 : -1;
  int jStep = (startPos.getJ() < stopPos.getJ()) ? 1 : -1;

  std::cout << "RoadPropagator::getPath" << std::endl;

  StringHelper::debug( 0xff, "(%d, %d) to (%d, %d)", startPos.getI(), startPos.getJ(), stopPos.getI(), stopPos.getJ() );
  
  if( startPos == stopPos )
  {
    oPathWay.push_back( &_d->startTile );
    return true;
  }
  
  std::cout << "propagate by I axis" << std::endl;
  
  // propagate on I axis
  for( TilePos tmp( startPos.getI(), stopPos.getJ() ); ; tmp+=TilePos( iStep, 0 ) )
  {
    const Tile& curTile = _d->tilemap.at( tmp );
         
    if( curTile.getTerrain().isConstructible() || curTile.getTerrain().isRoad() || curTile.getTerrain().isAqueduct() )
    {
      StringHelper::debug( 0xff, "+ (%d, %d)", curTile.getI(), curTile.getJ() );
      oPathWay.push_back( &curTile );
    }
    else
      return false;
    if (tmp.getI() == stopPos.getI())
      break;
  }

  std::cout << "propagate by J axis" << std::endl;
  // propagate on J axis
  for( int j = startPos.getJ();; j+=jStep )
  {
    const Tile& curTile = _d->tilemap.at( startPos.getI(), j );

    if( curTile.getTerrain().isConstructible() || curTile.getTerrain().isRoad() || curTile.getTerrain().isAqueduct() )
    {
      std::cout << "+ (" << curTile.getI() << " " << curTile.getJ() << ") ";
      oPathWay.push_back( &curTile );
    }
    else
      return false;

    if( j == stopPos.getJ() )
      break;
  }

  return true;
}
示例#7
0
void Garden::build( CityPtr city, const TilePos& pos )
{
  // this is the same arrangement of garden tiles as existed in C3
  int theGrid[2][2] = {{113, 110}, {112, 111}};

  Construction::build( city, pos );
  setPicture( ResourceGroup::entertaiment, theGrid[pos.getI() % 2][pos.getJ() % 2] );

  if( getSize().getArea() == 1 )
  {
    TilemapTiles tilesAround = city->getTilemap().getRectangle( getTilePos() - TilePos( 1, 1),
                                                                getTilePos() + TilePos( 1, 1 ) );
    foreach( Tile* tile, tilesAround )
    {
      GardenPtr garden = tile->getOverlay().as<Garden>();
      if( garden.isValid() )
      {
        garden->update();
      }
    }
示例#8
0
std::list<Tile*> Tilemap::getRectangle( const TilePos& start, const TilePos& stop, const bool corners /*= true*/ )
{
    std::list<Tile*> res;

    int delta_corners = 0;
    if (! corners)
    {
        delta_corners = 1;
    }

    /*Rect maxRect( 0, 0, _size, _size );
    Rect rect( start.getI()+delta_corners, start.getJ()+delta_corners, 
               stop.getI()-delta_corners, stop.getJ()-delta_corners );

    rect.constrainTo( maxRect );
    for( int i=rect.getLeft(); i < rect.getRight(); i++ )
        for( int j=rect.getTop(); j < rect.getBottom(); j++ )
            ret.push_back( &at( TilePos( i, j ) ) );
    */
    for(int i = start.getI()+delta_corners; i <= stop.getI()-delta_corners; ++i)
    {
        if (is_inside( TilePos( i, start.getJ() ) ))
        {
            res.push_back( &at(i, start.getJ() ));
        }

        if (is_inside( TilePos( i, stop.getJ() ) ))
        {
            res.push_back( &at( i, stop.getJ() ));
        }
    }

    for (int j = start.getJ()+1; j <= stop.getJ()-1; ++j)  // corners have been handled already
    {
        if (is_inside( TilePos( start.getI(), j ) ))
        {
            res.push_back(&at(start.getI(), j));
        }

        if (is_inside( TilePos( stop.getI(), j ) ))
        {
            res.push_back(&at(stop.getI(), j));
        }
    }

    return res;
}
示例#9
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;
}
示例#10
0
bool Pathfinder::pointIsWalkable( const TilePos& pos )
{
  return (pointExists( pos ) && grid[ pos.getI() ][ pos.getJ() ]->isWalkable() );
}
示例#11
0
bool Pathfinder::pointExists( const TilePos& pos )
{
  return ( pos.getI() < grid.size() && pos.getJ() < grid[pos.getI()].size() );
}
示例#12
0
bool Tilemap::is_inside(const TilePos& pos ) const
{
   return ( pos.getI() >= 0 && pos.getJ()>=0 && pos.getI()<_size && pos.getJ()<_size);
}
示例#13
0
 bool isValid( const TilePos& pos )
 {
   return ( pos.getI() >= 0 && pos.getJ() >= 0 && pos.getI() < (int)grid.size() && pos.getJ() < (int)grid[pos.getI()].size() );
 }
示例#14
0
void HighBridge::_checkParams( DirectionType& direction, TilePos& start, TilePos& stop, const TilePos& curPos ) const
{
  start = curPos;

  Tilemap& tilemap = Scenario::instance().getCity()->getTilemap();
  Tile& tile = tilemap.at( curPos );

  if( tile.getTerrain().isRoad() )
  {
    direction = D_NONE;
    return;
  }

  int imdId = tile.getTerrain().getOriginalImgId();
  if( imdId == 384 || imdId == 385 || imdId == 386 || imdId == 387 )
  {    
    PtrTilesArea tiles = tilemap.getFilledRectangle( curPos - TilePos( 10, 0), curPos );
    for( PtrTilesArea::reverse_iterator it=tiles.rbegin(); it != tiles.rend(); it++ )
    {
      imdId = (*it)->getTerrain().getOriginalImgId();
      if( imdId == 376 || imdId == 377 || imdId == 378 || imdId == 379 )
      {
        stop = (*it)->getIJ();
        direction = abs( stop.getI() - start.getI() ) > 3 ? D_NORTH_WEST : D_NONE;
        break;
      }
    }
  }
  else if( imdId == 376 || imdId == 377 || imdId == 378 || imdId == 379  )
  {
    PtrTilesArea tiles = tilemap.getFilledRectangle( curPos, curPos + TilePos( 10, 0) );
    for( PtrTilesArea::reverse_iterator it=tiles.rbegin(); it != tiles.rend(); it++ )
    {
      imdId = (*it)->getTerrain().getOriginalImgId();
      if( imdId == 384 || imdId == 385 || imdId == 386 || imdId == 387 )
      {
        stop = (*it)->getIJ();
        direction = abs( stop.getI() - start.getI() ) > 3 ? D_SOUTH_EAST : D_NONE;
        break;
      }
    }
  }
  else if( imdId == 372 || imdId == 373 || imdId == 374 || imdId == 375  )
  {
    PtrTilesArea tiles = tilemap.getFilledRectangle( curPos, curPos + TilePos( 0, 10) );
    for( PtrTilesArea::reverse_iterator it=tiles.rbegin(); it != tiles.rend(); it++ )
    {
      imdId = (*it)->getTerrain().getOriginalImgId();
      if( imdId == 380 || imdId == 381 || imdId == 382 || imdId == 383 )
      {
        stop = (*it)->getIJ();
        direction = abs( stop.getJ() - start.getJ() ) > 3 ? D_NORTH_EAST : D_NONE;
        break;
      }
    }
  }
  else if( imdId == 380 || imdId == 381 || imdId == 382 || imdId == 383 )
  {
    PtrTilesArea tiles = tilemap.getFilledRectangle( curPos - TilePos( 0, 10), curPos );
    for( PtrTilesArea::reverse_iterator it=tiles.rbegin(); it != tiles.rend(); it++ )
    {
      imdId = (*it)->getTerrain().getOriginalImgId();
      if( imdId == 372 || imdId == 373 || imdId == 374 || imdId == 375 )
      {
        stop = (*it)->getIJ();
        direction = abs( stop.getJ() - start.getJ() ) > 3 ? D_SOUTH_WEST : D_NONE;
        break;
      }
    }
  }
  else 
  {
    direction = D_NONE;
  }
}
示例#15
0
 int getHScore(AStarPoint* p)
 {
   TilePos pos = tile ? tile->getIJ() : TilePos( 0, 0 ); 
   TilePos otherPos = p->tile->getIJ();
   return (abs(otherPos.getI() - pos.getI()) + abs(otherPos.getJ() - pos.getJ())) * 10;
 }
示例#16
0
std::string Json::serialize(const Variant &data, bool &success, const std::string& tab)
{
  std::string str;
  success = true;

  if( !data.isValid() ) // invalid or null?
  {
    str = "null";
  }

  else if( (data.type() == Variant::List) || (data.type() == Variant::NStringArray) ) // variant is a list?
  {
    StringArray values;
    const VariantList rlist = data.toList();
    for( VariantList::const_iterator it = rlist.begin(); it != rlist.end(); it++)
    {
      std::string serializedValue = serialize( *it, "" );
      if( serializedValue.empty() )
      {
          success = false;
          break;
      }

      values.push_back( serializedValue );
    }

    str = "[ " + join( values, ", " ) + " ]";
  }
// 	else if(data.type() == Variant::Hash) // variant is a hash?
// 	{
// 		const VariantHash vhash = data.toHash();
// 		QHashIterator<std::string, Variant> it( vhash );
// 		str = "{ ";
// 		QList<QByteArray> pairs;
// 
// 		while(it.hasNext())
// 		{
// 			it.next();
//               QByteArray serializedValue = serialize(it.value(), "");
// 
// 			if(serializedValue.isNull())
// 			{
// 				success = false;
// 				break;
// 			}
// 
//               pairs << tab.toAscii() + sanitizeString(it.key()).toUtf8() + " : " + serializedValue;
// 		}
// 
// 		str += join(pairs, ", ");
// 		str += " }";
// 	}
    else if(data.type() == Variant::Map) // variant is a map?
    {
      VariantMap vmap = data.toMap();
      
      str = "{ \n";
      StringArray pairs;
      for( VariantMap::iterator it = vmap.begin(); it != vmap.end(); it++ )
      {        
        std::string serializedValue = serialize( it->second, tab + "  ");
        if( serializedValue.empty())
        {
                //success = false;
          pairs.push_back( tab + sanitizeString( it->first ) + std::string( " : \"nonSerializableValue\"" ) );
          continue;
        }
        pairs.push_back( tab + sanitizeString( it->first ) + " : " + serializedValue );
      }
      str += join(pairs, ",\n");
      std::string rtab( tab );
      rtab.resize( std::max<int>( 0, tab.size() - 2 ) );
      str += std::string( "\n" ) + rtab + "}";
    }
    else if((data.type() == Variant::String) || (data.type() == Variant::NByteArray)) // a string or a byte array?
    {
            str = sanitizeString( data.toString() );
    }
    else if(data.type() == Variant::Double || data.type() == Variant::Float) // double?
    {
      str = StringHelper::format( 0xff, "\"%f\"", data.toDouble() );
      if( str.find(".") == std::string::npos && str.find("e") == std::string::npos )
      {
         str += ".0";
      }
    }
    else if( data.type() == Variant::NTilePos)
    {
      TilePos pos = data.toTilePos();
      str = StringHelper::format( 0xff, "[ %d, %d ]", pos.getI(), pos.getJ() );
    }
    else if( data.type() == Variant::NSize)
    {
      Size size = data.toSize();
      str = StringHelper::format( 0xff, "[ %d, %d ]", size.getWidth(), size.getHeight() );
    }
    else if( data.type() == Variant::NPoint)
    {
      Point pos = data.toPoint();
      str = StringHelper::format( 0xff, "[ %d, %d ]", pos.getX(), pos.getY() );
    }
    else if( data.type() == Variant::NPointF)
    {
      PointF pos = data.toPointF();
      str = StringHelper::format( 0xff, "[ \"%f\", \"%f\" ]", pos.getX(), pos.getY() );
    }
    else if (data.type() == Variant::Bool) // boolean value?
    {
      str = data.toBool() ? "true" : "false";
    }
    else if (data.type() == Variant::ULongLong) // large unsigned number?
    {
      str = StringHelper::format( 0xff, "%u", data.toULongLong() );
    }
    else if ( data.canConvert( Variant::LongLong ) ) // any signed number?
    {
      str = StringHelper::format( 0xff, "%d", data.toLongLong() );
    }
    else if (data.canConvert( Variant::Long ))
    {
      str = StringHelper::format( 0xff, "%d", data.toLongLong() );
    }
    else if (data.canConvert( Variant::String ) ) // can value be converted to string?
    {
      // this will catch Date, DateTime, Url, ...
      str = sanitizeString( data.toString() );
    }
    else
    {
      success = false;
    }

    if (success)
    {
            return str;
    }
    else
    {
      return std::string();
    }
}