随机化对象的位置

时间:2012-05-23 21:32:51

标签: c# performance algorithm

只是附加信息:这是我正在进行的游戏项目。

我正在尝试制作一种有效的随机化算法,在给定可用空间的长度的情况下放置多个对象(彼此排列)。

直接问题:给定一个length = lengthOfArea的可用空间,以及要定位的对象数= numObjects,其中每个对象的长度为lengthObject =(lengthOfArea / 2)/ numObjects。 (这样,物体占据的空间总量是可用空间长度的一半)。

我应该寻找每个对象的中心位置并返回它的数组。

这是我目前的尝试:

public int[] FindObjectPositions(int lengthOfArea, int numObjects, Random random)
  {
    int lengthOfObject = (lengthOfArea / 2) / numObjects;
    int[] positionsPicked = new int[numObjects];
    int minPosition = lengthObject / 2;
    int maxPosition = lengthOfArea - (lengthObject / 2);
    for (int i = 0; i < numObjects; i++)
    {
      int newPosition;
      do 
        {
          newPosition = minPosition + random.Next(maxPosition - minPosition);
        } while (!IsPositionValid(positionsPicked, newPosition, lengthObject));
        positionsPicked[i] = newPosition;
    }
    return positionsPicked;
  }

public bool IsPositionValid(int[] positionsPicked, int newPosition, int lengthObject)
  {
    for (int i = 0; i < positionsPicked.Length; i++)
    {
      if (Math.Abs(positionsPicked[i] - newPosition) <= (lengthObject / 2))
        return false;
    }
    return true;
  }

基本上我正在做的是我不断地为每个对象随机找到一个有效的位置。我只是想知道它是否效率低下。另外,我想知道我是否会用这种方法陷入僵局?

1 个答案:

答案 0 :(得分:1)

如果存在无法容纳更多对象的配置,则可能会死锁。例如,如果有30个空格,并且每个对象的长度为5个空格,则配置

_ _ _ _ x x x x x _ _ _ _ x x x x x _ _ _ _ x x x x x _ _ _

没有可能适合另一个物体的地方,即使有15个空地!


假设有m个空格,每个对象的宽度为w。一种不会死锁的方法是生成m-w+1个数字1, 2, ..., m-w, m-w+1的列表。然后随机选择一个 - 这将代表对象的最左侧位置。然后删除该数字右侧和左侧w-1个数字 - 这表示对象宽w,宽度为w的其他对象}将适合它左侧的w-1个空格。

例如,如果m = 20w = 3

  

创建1到18的列表

     

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

     

然后随机选择一个。假设我们选择10.然后空格10,11,12被我们的对象填充,空格8,9不能是另一个对象的最左边位置,所以我们删除了数字8到12。

     

1 2 3 4 5 6 7 13 14 15 16 17 18

     

说我们接下来选择18。然后我们删除16-18:

     

1 2 3 4 5 6 7 13 14 15

     

依此类推,直到我们没有数字为止。


上面的方法不会死锁,但它有另一个问题:它可能可能配置(比方说)6个对象,但上面的方法可能只生成一个配置其中有4或5个物体,没有任何余地。要解决这个问题,我们可以计算出6个对象应该有多少个空格,而不是为我们的对象选择随机位置,而是选择空格的随机点(使用上面的方法)。

这将为您提供所需的对象数量,随机分布,不会出现死锁。