예제 #1
0
void SC2Map::getShortestPathPredecessors( Base* b0, Base* b1, PathType t,
                                          Node** uOut, Node** vOut )
{
  float dShortest = infinity;

  for( map<Node*, float>::iterator itr0 = (b0->node2patchDistance[t]).begin();
       itr0 != (b0->node2patchDistance[t]).end();
       ++itr0 )
  {
    Node* u       = itr0->first;
    float dPatch0 = itr0->second;


    for( map<Node*, float>::iterator itr1 = (b1->node2patchDistance[t]).begin();
         itr1 != (b1->node2patchDistance[t]).end();
         ++itr1 )
    {
      Node* v       = itr1->first;
      float dPatch1 = itr1->second;


      float dRoute = getShortestPathDistance( u, v, t );

      if( dPatch0 + dPatch1 + dRoute < dShortest )
      {
        dShortest = dPatch0 + dPatch1 + dRoute;

        *uOut = u;
        *vOut = v;
      }
    }
  }
}
예제 #2
0
Node* SC2Map::getShortestPathPredecessor( Node* u, Base* b, PathType t )
{
  if( !(u->pathsFromThisSrcCalculated) )
  {
    computeShortestPaths( u, t );
    u->pathsFromThisSrcCalculated = true;
  }

  float dShortest = infinity;
  Node* pred      = NULL;

  for( map<Node*, float>::iterator itr = (b->node2patchDistance[t]).begin();
       itr != (b->node2patchDistance[t]).end();
       ++itr )
  {
    Node* v      = itr->first;
    float dPatch = itr->second;
    float dRoute = getShortestPathDistance( u, v, t );

    if( dPatch + dRoute < dShortest )
    {
      dShortest = dPatch + dRoute;
      pred      = v;
    }
  }

  return pred;
}
예제 #3
0
float SC2Map::getShortestPathDistance( Base* b1, Base* b2, PathType t )
{
  float dShortest = infinity;

  for( map<Node*, float>::iterator itr1 = (b1->node2patchDistance[t]).begin();
       itr1 != (b1->node2patchDistance[t]).end();
       ++itr1 )
  {
    Node* u       = itr1->first;
    float dPatch1 = itr1->second;


    for( map<Node*, float>::iterator itr2 = (b2->node2patchDistance[t]).begin();
         itr2 != (b2->node2patchDistance[t]).end();
         ++itr2 )
    {
      Node* v       = itr2->first;
      float dPatch2 = itr2->second;


      float dRoute = getShortestPathDistance( u, v, t );

      if( dPatch1 + dPatch2 + dRoute < dShortest )
      {
        dShortest = dPatch1 + dPatch2 + dRoute;
      }
    }
  }

  return dShortest;
}
예제 #4
0
float SC2Map::getShortestPathDistance( point* p, Base* b, PathType t )
{
  if( !isPlayableCell( p ) )
  {
    return infinity;
  }

  Node* u = getPathNode( p, t );
  if( u == NULL )
  {
    return infinity;
  }

  return getShortestPathDistance( u, b, t );
}
예제 #5
0
float SC2Map::getShortestPathDistance( point* src, point* dst, PathType t )
{
  if( !isPlayableCell( src ) || !isPlayableCell( dst ) )
  {
    return infinity;
  }

  Node* u = getPathNode( src, t );
  Node* v = getPathNode( dst, t );

  if( u == NULL || v == NULL )
  {
    return infinity;
  }

  return getShortestPathDistance( u, v, t );
}
예제 #6
0
void SC2Map::locateChokes()
{
  for( list<StartLoc*>::const_iterator itr1 = startLocs.begin();
       itr1 != startLocs.end();
       ++itr1 )
  {
    StartLoc* sl1 = *itr1;

    list<point> possibleChokes;


    for( list<StartLoc*>::const_iterator itr2 = startLocs.begin();
         itr2 != startLocs.end();
         ++itr2 )
    {
      StartLoc* sl2 = *itr2;

      if( sl1 == sl2 )
      {
        continue;
      }

      Node* src = getPathNode( &(sl2->loc), pathTypeLocateChokes );
      Node* u   = getPathNode( &(sl1->loc), pathTypeLocateChokes );

      if( src == NULL )
      {
        printError( "Start location %s is in an unpathable cell.\n",
                    sl2->name );
        exit( -1 );
      }

      if( u == NULL )
      {
        printError( "Start location %s is in an unpathable cell.\n",
                    sl1->name );
        exit( -1 );
      }

      Node* v = getShortestPathPredecessor( src, u, pathTypeLocateChokes );
      if( v == NULL )
      {
        // no path, just skip this pairing
        continue;
      }

      // The choke should be closer than 50% of the distance
      // from a start location to any other start location
      float dTotal = getShortestPathDistance( src, u, pathTypeLocateChokes );
      float dTest  = dTotal;

      point pBest;
      pBest.mSet( -1000.0f + sl2->loc.mx,
                  -1000.0f + sl2->loc.my );

      float dChokeMin = infinity;
      bool trippedThreshold = false;

      while( v != NULL && dTest > 0.5f*dTotal )
      {
        float dChoke = chokeDistance( &(v->loc), pathTypeLocateChokes );

        if( trippedThreshold && dChoke > dChokeMin )
        {
          // we just got a worse result, kick out
          break;
        }

        if( dChoke < getfConstant( "chokeDetectionThreshold" ) )
        {
          trippedThreshold = true;

          dChokeMin = dChoke;
          pBest.set( &(v->loc) );
        }

        u     = v;
        v     = getShortestPathPredecessor( src, u, pathTypeLocateChokes );
        dTest = getShortestPathDistance   ( src, u, pathTypeLocateChokes );
      }

      possibleChokes.push_back( pBest );
    }

    // if the best choke from this location to all others
    // is reasonably close, take the average
    bool  chokesAgree = true;
    float xTotal = 0.0f;
    float yTotal = 0.0f;
    for( list<point>::iterator itr1 = possibleChokes.begin();
         chokesAgree && itr1 != possibleChokes.end();
         ++itr1 )
    {
      point c1;
      c1.pcSet( (*itr1).pcx, (*itr1).pcy );

      list<point>::iterator itr2 = itr1;
      ++itr2;
      for( ;
           itr2 != possibleChokes.end();
           ++itr2 )
      {
        point c2;
        c2.pcSet( (*itr2).pcx, (*itr2).pcy );

        if( p2pDistance( &c1, &c2 ) > getfConstant( "chokeDetectionAgreement" ) )
        {
          chokesAgree = false;
          break;
        }
      }

      xTotal += c1.mx;
      yTotal += c1.my;
    }

    if( chokesAgree )
    {
      float xAvg = xTotal / (float)possibleChokes.size();
      float yAvg = yTotal / (float)possibleChokes.size();
      sl1->mainChoke.mSet( xAvg, yAvg );

    } else {
      printWarning( "Could not locate main choke for start location %s.\n",
                    sl1->name );
      sl1->mainChoke.mSet( -1.0f, -1.0f );
    }
  }
}