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