Прошу объяснить, как работает указатель стека при рекурсивном вызове метода из самого себя. Пишу морской на Java. В классе "Корабль" есть метод, который задает кораблю случайные координаты (X и Y). В этом методы стоит проверка, не зайдет ли корабль с этими координатами за границы поля, и если зайдет, то метод метод вызывает сам себя.
if (orientation == Orientation.VERTICAL) {
if (y > GameMap.HEIGTH - body.length) {
if (resetCount == 10) {
resetCount = 0;
orientation = Orientation.HORIZONTAL;
orientationLock = true;
}
resetCount++;
this.resetCoordinates();
this.setRandomCoordinates();
}
for (int i = 0; i < body.length; i++) {
body[i].setY(y++);
body[i].setX(x);
}
Была проблема, что после срабатывания этой проверки корабль, при успешном прохождении новой проверки, корректно отрабатывал присвоение координат, но после этого снова начинал их задавать, причем со старыми значениями (до входа в рекурсию) X и Y.
Бился несколько часов, прежде чем понял, что надо было изменить код таким образом, то есть добавить ветвление после IF:
else {
for (int i = 0; i < body.length; i++) {
body[i].setY(y++);
body[i].setX(x);
}
}
Я считал, что, если код входит в IF в рекурсией, то до следующих строк он уже не дойдет - произойдет новый вызов, после чего заново будет проверяться условие. Очевидно, что это не так.
Правильно ли я понял, что рекурсия - как клубок, возвращается до места, откуда была вызвана, и продолжает выполнение с точки вызова, запоминая состояние?
Весь код метода после исправления:
public void setRandomCoordinates() {
Random rand = new Random();
int setOrientation = rand.nextInt(2);
if (!orientationLock) {
orientation = setOrientation == 0 ? Orientation.HORIZONTAL : Orientation.VERTICAL;
}
int x = rand.nextInt(10);
int y = rand.nextInt(10);
if (orientation == Orientation.VERTICAL) {
if (y > GameMap.HEIGTH - body.length) {
if (resetCount == 10) {
resetCount = 0;
orientation = Orientation.HORIZONTAL;
orientationLock = true;
}
resetCount++;
this.resetCoordinates();
this.setRandomCoordinates();
} else {
for (int i = 0; i < body.length; i++) {
body[i].setY(y++);
body[i].setX(x);
}
}
} else if (orientation == Orientation.HORIZONTAL) {
if (x > GameMap.WIDTH - body.length) {
if (resetCount == 10) {
resetCount = 0;
orientation = Orientation.VERTICAL;
orientationLock = true;
}
resetCount++;
this.resetCoordinates();
this.setRandomCoordinates();
} else {
for (int i = 0; i < body.length; i++) {
body[i].setY(y);
body[i].setX(x++);
}
}
}
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Мне нужно сделать, чтобы у меня три label были вверху окна (друг за другом) в полную ширину, один внизу окна, а в центре находилась формаМожет...