Exemple #1
0
PatchMap<1>* Cartographer::buildAdjacencyMap(const UnitType *uType, const Vec2i &pos,
        CardinalDir facing, Field f, int size) {
    PF_TRACE();
    const Vec2i mapPos = pos + (OrdinalOffsets[odNorthWest] * size);
    const int sx = pos.x;
    const int sy = pos.y;

    Rectangle rect(mapPos.x, mapPos.y, uType->getSize() + 2 + size, uType->getSize() + 2 + size);
    PatchMap<1> *pMap = new PatchMap<1>(rect, 0);
    pMap->zeroMap();

    PatchMap<1> tmpMap(rect, 0);
    tmpMap.zeroMap();

    // mark cells occupied by unitType at pos (on tmpMap)
    Util::RectIterator rIter(pos, pos + Vec2i(uType->getSize() - 1));
    while (rIter.more()) {
        Vec2i gpos = rIter.next();
        if (!uType->hasCellMap() || uType->getCellMapCell(gpos.x - sx, gpos.y - sy, facing)) {
            tmpMap.setInfluence(gpos, 1);
        }
    }

    // mark goal cells on result map
    rIter = Util::RectIterator(mapPos, pos + Vec2i(uType->getSize()));
    while (rIter.more()) {
        Vec2i gpos = rIter.next();
        if (tmpMap.getInfluence(gpos) || !masterMap->canOccupy(gpos, size, f)) {
            continue; // building or obstacle
        }
        Util::PerimeterIterator pIter(gpos - Vec2i(1), gpos + Vec2i(size));
        while (pIter.more()) {
            if (tmpMap.getInfluence(pIter.next())) {
                pMap->setInfluence(gpos, 1);
                break;
            }
        }
    }
    return pMap;
}
Exemple #2
0
//----------------------------------------------------------------------------
               unsigned  int LayMap::search(int x,int y,layerType layer)
//
// Method  of searching is very simple : this function is called recursively
// for all still not visited points in the vicinity of (x,y),or other points
// in universal feed or tries to change layer if there's a via. If all these
// possibilities are already checked it returns 0.
{
  unsigned int net;
  layoutMapType *m=&map[x-xMin][y-yMin];

  if (m->visited & layer)          // we've already been here !
    return 0;            

  if ( m->termNo )
    switch (layer)
    {
    case DiffusionLayer:
    case PolyLayer:
                  if (!(m->layers & Metal1Layer)&& !(m->layers & Metal2Layer))
		    return m->termNo;
		  break;
    case Metal1Layer:
                  if (!(m->layers & Metal2Layer))
		    return m->termNo;
		  break;
    case Metal2Layer:
		  return m->termNo;
    }


  m->visited |= layer;               // mark that place
  

  // visiting points belonging to the same layer :



  if(layer != PolyLayer)             // restricted feeds && metal segments
  {
                                     // we have only to check this neighbors
                                     // which have connection with our on
                                     // the same layer
    if(m->leftWay & layer && x > xMin)
      if ( net = search(x-1,y,layer) )
	return net;
    if(m->upWay & layer && y < yMax)
      if ( net = search(x,y+1,layer) )
	return net;
    if(m->rightWay & layer && x < xMax)
      if ( net = search(x+1,y,layer) )
	return net;
    if(m->downWay & layer && y > yMin)
      if ( net = search(x,y-1,layer) )
	return net;
	
  }
  else                                // for universal feed we have to
                                      // go to visit all of the points from the 
                                      // list
  {

    ListIterator rIter(  (List&)(*imageMap)[m->uniNo] );
    int a = x / imageMap->cols ,
        b = y / imageMap->rows;
    
    if (x<0)
      a--;
    if (y<0)
      b--;

    a*=imageMap->cols;
    b*=imageMap->rows;
                          // now we have coordinates of left-bottom point
                          // in cluster

    for(;(Item&)rIter != NOITEM;rIter++)
    {
      Point &p = (Point&)(Item&)rIter;
      if ( (x!= a+p.x || y!= b+p.y) && (net = search(a+p.x,b+p.y,layer))>0 )
	return net;
    }
  }


  // if all points on this layer visited lets try go to the other


  if(m->layers & ViaLayer)          // normal via exists 
    if ( (layer & Metal1Layer) || (layer & Metal2Layer) )
    {
      if( net = search(x,y,(m->layers & PolyLayer)>0 ? PolyLayer : DiffusionLayer))
	return net;
    }
    else
    {
      if( net = search(x,y,(m->layers & Metal1Layer) ? Metal1Layer : Metal2Layer))
	return net;
    }

  if((m->layers  & MetalsViaLayer)>0)   // via between two metals
    if ( (layer & Metal1Layer)>0  )
    {  
      if( net = search(x,y,Metal2Layer))
	return net;
    }
    else
    {
      if( net = search(x,y,Metal1Layer))
	return net;
    }  

  

  // we cannot go further - must return

  return 0;

}// LayMap::search  //