рекурсивный + 900 элементов + соседняя проверка = вызывает stackoverflow

Я имею городскую игру моделирования и пытаюсь найти способ проверить поток нашей энергосистемы. Основы: карта для города основана на мозаиках (мозаики 30 на 30 = 900 мозаик). Теперь я запускаю на электростанции и делаю рекурсивную соседнюю проверку (вершина, оставленная, право, нижняя часть), чтобы проверить, существует ли что-то, что транспортирует питание. Если существует что-то, я начинаю проверять, что это размещает рядом для соседей, также. Для предотвращения двойных проверок и/или бесконечных рекурсивных вызовов я заполняю ArrayList обработанными мозаиками и проверкой, если новая мозаика была уже обработана и добавила к ArrayList...

Рекурсивно запущенный:

public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
    Log.w("GT", "update env for id: " + id);
    int newId = id - GameMap.mMapSize;
    if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
            && !elements.contains(newId)) {
        elements.add(newId);
        updatePowerEnvironment(newId, elements);
    }
    newId = id + GameMap.mMapSize;
    if (newId < GameMap.mMapCells.size() && GameMap.mMapCells.get(newId).mPowerEnabled
            && !elements.contains(newId)) {
        elements.add(newId);
        updatePowerEnvironment(newId, elements);
    }
    newId = id - 1;
    if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
            && !elements.contains(newId)) {
        elements.add(newId);
        updatePowerEnvironment(newId, elements);
    }
    newId = id + 1;
    if (newId < GameMap.mMapCells.size()
            && GameMap.mMapCells.get(newId).mPowerEnabled
            && !elements.contains(newId)) {
        elements.add(newId);
        updatePowerEnvironment(newId, elements);
    }
}

Если я могу доверять выводу журнала, никакую мозаику не попробовали к обработанному дважды. Это означает, что у меня нет ошибок в рекурсивных вызовах. Который также означает, стек является просто слишком маленьким.

У кого-то есть идея, как избежать предела стека?

[Обновление и мой код в результате ответа Erics]

public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
    Stack<Integer> toProcess = new Stack<Integer>();
    toProcess.push(id);
    int mapSize = GameMap.mMapCells.size();
    while (!toProcess.empty()) {
        id = toProcess.pop();
        Log.e("GT", "id to process: " + id);
        if (elements.contains(id)) {
            continue;
        }
        int[] neighborIds = computeNeighbors(id);
        for (int neighbor : neighborIds) {
            if (neighbor < 0 || neighbor >= mapSize) {
                continue;
            }
            if (!GameMap.mMapCells.get(neighbor).mPowerEnabled) {
                continue;
            }
            toProcess.push(neighbor);
        }
        elements.add(id);
    }
}

private int[] computeNeighbors(int id) {
    return new int[] {id + GameMap.mMapSize, id - GameMap.mMapSize, id + 1, id - 1};
}
5
задан WarrenFaith 29 July 2010 в 21:42
поделиться