Я имею городскую игру моделирования и пытаюсь найти способ проверить поток нашей энергосистемы. Основы: карта для города основана на мозаиках (мозаики 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};
}