まず、target!=replacement
('FloodFill' の最初の呼び出しの前に 1 回実行できます) ことを確認する必要があります。次に、_mapWidth と _mapHeight が異常に大きくない限り (_mapLayers 配列の内容に大きく依存します)、アルゴリズムが機能する可能性があります。これが問題になる場合は、非再帰アルゴリズムを試してください。作成する
class Point
{
public int x, y;
public Point(int newX, int newY)
{
x=newX;
y=newY;
}
}
そして
List<Point> pointList;
最初の点をこのリストに入れ、pointList が空になるまで何らかのループを実行します。リストから 1 つの点を取り出し、上記のように処理し、上記の元の再帰呼び出しの代わりに、4 つの隣接点を再びリストに入れます。
編集:ここに完全な例がありますが、テストはしていません:
void FloodFill2(int layer, int xStart, int yStart, int target, int replacement)
{
if(target==replacement)
return;
List<Point> pointList = new List<Point>();
pointList.Add(new Point(xStart,yStart));
while(pointList.Count>0)
{
Point p = pointList[pointList.Count-1];
pointList.RemoveAt(pointList.Count-1);
if (p.x < 0) continue;
if (p.y < 0) continue;
if (p.x >= _mapWidth) continue;
if (p.y >= _mapHeight) continue;
if (_mapLayers[layer, p.x, p.y] != target) continue;
_mapLayers[layer, p.x, p.y] = replacement;
pointList.Add(new Point(p.x - 1, p.y));
pointList.Add(new Point(p.x + 1, p.y));
pointList.Add(new Point(p.x, p.y - 1));
pointList.Add(new Point(p.x, p.y + 1));
}
}
EDIT2:実際、ルーチンを最適化するための提案があります。挿入が無意味になる場合は、リストへの挿入を避けてください。
if(p.x>=0)
pointList.Add(new Point(p.x - 1, p.y));
if(p.x<_mapWidth-1)
pointList.Add(new Point(p.x + 1, p.y));
if(p.y>=0)
pointList.Add(new Point(p.x, p.y - 1));
if(p.y<_mapHeight-1)
pointList.Add(new Point(p.x, p.y + 1));