分组2D实例数组

时间:2013-04-01 15:12:35

标签: c++ optimization 2d-games

我有一个可行的解决方案,但我确信必须有更好的实施方案。在坚果壳中,问题是:

我正在开发一个连接> = 3,宝石迷阵风格的益智游戏。当'板'的状态发生变化时,我将所有部分分组,这样如果它们在水平或垂直方向上“连接”,它们就会共享一个ID。这就是我目前的做法:

[伪]

for all( array object* )
{
    if !in_a_group() check_neighbours( this )
}

void check_neighbours( ID )
{
    if ( check_is_same_type( left ) )
    { 
        if !in_a_group() this.ID = ID ; check_neighbours( ID )
        else if( in_a_group ) change_IDs(this.ID, ID ) 
    }
    same for right ...
    up ...
    down ...     
}

这是我所做的非常虚伪的伪版本。 我递归调用check_neighbours,向前传递第一个分支的ID(我使用这个指针作为ID而不是生成一个)。

如果我找到一个具有不同ID的连接件,我会用新ID覆盖所有具有该ID的件(我这里有一个ASSERT,因为它实际上不应该发生。它在很多测试中还没有到目前为止)

除非作品没有ID,否则我不会在原始分支处check_neighbours。

这很好用,虽然我的伪可能缺少一些小逻辑。 我的问题是它有可能使用许多分支(这可能是我正在处理的硬件上的问题)。我已经解决了这个问题,现在我看不到另一种解决方案了。你是否觉得自己错过了一些非常明显的东西?

我也是stackoverflow的新手,对编程很新,对礼节等方面的任何建议都很受欢迎。

1 个答案:

答案 0 :(得分:0)

  

您如何建议避免递归?

据我所知,你的算法基本上是一个“泛滥填充”,但有一点点扭曲。

无论如何,为了避免递归,您需要分配数组来存储未处理项的坐标并使用queue或fifo。因为你知道网格的维度(因为它是宝石迷阵式(?)游戏,你应该能够在任何地方预先分配它。

任何泛洪填充类型递归算法的伪代码。

struct Coord{
    int x, y;
}

typedef std::queue<Coord> CoordQueue;

bool validCoord(Coord coord){
    return (coord.x >= 0) && (coord.y >= 0) 
        && (coord.x < boardSizeX) && (coord.y < boardSizeY);
}

bool mustProcessCoord(Coord coord);

void processAll(){
     CoordQueue coordQueue;
     Coord startPoint = Coord(0, 0);
     coordQueue.pushBack(startPoint);

     while (!coordQueue.empty()){
         const Coord &curCoord = coordQueue.front();
         //do something with current coordinates.
         processCoord(curCoord);

         const int numOffsets = 4;
         const int offsets[numOffsets][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
         for (int offsetIndex = 0; offsetIndex < numOffsets; offsetIndex++){
              Coord neighborCoord = Coord(curCoord.x + offsets[offsetIndex][0],
                    curCoord.y + offsets[offsetIndex][1]); 
              if (!isValidCoord(neighborCoord) || !mustProcessCoord(neighborCoord))
                  continue;
              coordQueue.push_back(neighborCoord);
         }

         coordQueue.pop_front();
     }
}

看?没有递归,只是一个循环。几乎任何递归函数都可以打包成类似的东西。

如果您的底层平台是限制性的并且您没有std :: queue,则使用array(实现为数组的环形缓冲区可以像fifo队列一样)。因为您知道电路板的大小,所以可以预先计算阵列的大小。其余的应该很容易。