C ++:检查向量中所有对象属性的值

时间:2014-11-27 06:15:07

标签: c++ vector

我认为最好用一些伪代码来解释:

std::vector<Yes> objs;
//The Yes Class constructor: Yes(x,y)
//Let's imagine I instantiated this vector with one object somewhere appropriately

void inSomeFunction()
{
   for(int i = 0; i < 20; ++i)
   {
      int randX = rand() % mapWidth;
      int randY = rand() % mapHeight;

      for(int j = 0; j < objs.size(); ++j)
      {
         if(randX > x + threshold, for all objects in my vector && randY > y + threshold, for all objects in my vector)
         {
            objs.push_back(Yes(randX,randY));
         }
      }
   }
}

所以我有一个窗口,其尺寸为mapWidth和mapHeight,我基本上只是想在xy平面上制作20个彼此不重叠的对象。

我还想确保randX和randY不重叠,但也要与所有其他现有对象保持一定的阈值距离。所以,让我们说我的阈值= 20,然后我想确保randX和randY不包含在矢量中任何/所有现有对象周围的半径为20的圆圈中。

清晰度示例:首先是对象是(x,y)=(10,20),我的阈值= 20,我想创建第二个对象,以randX和randY为参数,并将其推入我的向量;但是,我想确保点(randX,randY)不在半径为20的圆中,并且以(10,20)为中心,这是我第一个对象的坐标。程序可以生成另一个随机(x,y)或者只是生成randX和randY以适应我想要的条件,但是我需要它在我创建更多对象时继续检查向量中的所有对象。

我想知道如何做到这一点?同样为了更清晰,它也适用于游戏。我试图在2D地图中生成多个建筑物,但我显然不希望它们重叠或彼此靠近。我将如何完成这项工作?

3 个答案:

答案 0 :(得分:1)

我会把它分解成更小的功能 像这样:

bool overlaps(const Yes& thing, int x, int y)
{
   // See if (x, y) overlaps 'thing' in whichever way is appropriate.
}

bool overlaps_any(const std::vector<Yes>& things, int x, int y)
{
   for (const Yes& thing : things)
   {
      if (overlaps(thing, x, y))
      {
         return true;
      }
   }
   return false;
}

void inSomeFunction(std::vector<Yes>& objs)
{
   for(int i = 0; i < 20; ++i)
   {
      int x = 0;
      int y = 0;
      do {
         x = rand() % mapWidth;
         y = rand() % mapHeight;
      } while (overlaps_any(objs, x, y));
      objs.push_back(Yes(x,y));
    }
}

可能有更有效的方法,但由于您只生成一次地图,我现在不会担心效率。

答案 1 :(得分:0)

这是迭代向量的方法。您可以自己将元素与您希望的值进行比较。

std::vector<Object> objs;

void inSomeFunction()
{
    for (int i = 0; i < 20; ++i)
    {
        int randX = rand() % mapWidth;
        int randY = rand() % mapHeight;

        for (std::vector<Object>::iterator itrObj = objs.begin(); itrObj != objs.end(); ++itrObj)
        {
            //Here you can access with operator -> the members of the class
            //itrObj->x
            //Or
            //(*itrObj).x
            //This is how you iterate through a std::vector<T>
            //
            //Do stuff with the values here
            //
            //If you do not wish to change the members
            //of the class Object stored in this vector and only compare them
            //use a const_iterator instead of iterator
        }
    }

这是一种检查它是否在范围内的方法:

struct Window
{
    Window (int x, int y, int width, int height)
        : x(x)
        , y(y)
        , width(width)
        , height(height)
    {}
    int x;
    int y;
    int width;
    int height;
};

struct Position
{
    Position (int x, int y)
        : x(x)
        , y(y)
    {}
    int x;
    int y;
};

bool IsWithinRange (const Window &Range, const Position &Check)
{
    int r_x         = Range.x,
        r_y         = Range.y,
        r_width     = Range.width,
        r_height    = Range.height,
        r_max_x     = r_width + r_x,
        r_max_y     = r_height + r_y;

    if (Check.x >= r_x && Check.x <= r_max_x)
        if (Check.y >= r_y && Check.y <= r_max_y)
            return true;
    return false;
}

我不确定您的Object类是如何构建的,但我确定您可以进行微小的调整。

答案 2 :(得分:0)

我将根据我正在阅读的内容走出这里。可能不是最好的方式,但很简单。如果不完全了解您的项目,很难说。但是,如果你给我们完整的项目,我们会告诉你要像你已经做的那样缩短。所以,我认为你最好在这个问题上获得推测性答案。

尽管如此,一个想法:

创建您可以拥有的max-x和max-y的2D布尔数组。对于每个对象,通过将值设置为true,将占用该数组中的x,y空间。然后,您可以通过扫描到目前为止的给定随机值来检查某些内容是否太近,或者它是否已经在使用中。