Название вашего вопроса содержит «рекурсивный», поэтому я искал рекурсивное решение.Для каждой комнаты вы можете сказать: если одна из соседних комнат ведет к целевой комнате, то я тоже часть пути.Когда ни один из ваших соседей не ведет к цели, вы также не участвуете в пути.
Чтобы сделать его рекурсивным, я создал новый метод, который начинается с текущей комнаты.Общий путь и список посещенных комнат определяются как переменные класса, поэтому они все еще доступны после всех вызовов checkRoom
.
package pathing;
import java.util.ArrayList;
import java.util.List;
import room.Room;
public class Path {
// list of all visited rooms to detect loops
List<Room> visited = new ArrayList<>();
// path from start to the current room
List<Room> path = new ArrayList<>();
Room target;
boolean pathFound=false;
public void checkRoom(Room current) {
if(pathFound) {
return;
}
if(visited.contains(current))
{
// we've been here before, we have detected a loop
return;
}
path.add(current);
visited.add(current);
if (current.equals(target)) {
pathFound=true;
} else {
// there are always neighbours (at least the room we come from
for (Room room : current.getNeighbours()) {
checkRoom(room);
if(pathFound) {
return;
}
}
// all neighbours processed without success
path.remove(current);
}
}
public static List<Room> findPath(Room start, Room target) {
Path p=new Path();
p.target=target;
p.checkRoom(start);
return p.path;
}
public static void main (String args[])
{
// 2 - 3 - 4
// | |
// 1 - 5
// |
// 6 - 7 - 9
// |
// 8
Room room1=new Room(1,new ArrayList<Room>());
Room room2=new Room(2,new ArrayList<Room>());
Room room3=new Room(3,new ArrayList<Room>());
Room room4=new Room(4,new ArrayList<Room>());
Room room5=new Room(5,new ArrayList<Room>());
Room room6=new Room(6,new ArrayList<Room>());
Room room7=new Room(7,new ArrayList<Room>());
Room room8=new Room(8,new ArrayList<Room>());
Room room9=new Room(9,new ArrayList<Room>());
room1.getNeighbours().add(room2);
room1.getNeighbours().add(room5);
room1.getNeighbours().add(room6);
room2.getNeighbours().add(room1);
room2.getNeighbours().add(room3);
room3.getNeighbours().add(room2);
room3.getNeighbours().add(room4);
room4.getNeighbours().add(room3);
room5.getNeighbours().add(room3);
room5.getNeighbours().add(room1);
room6.getNeighbours().add(room1);
room6.getNeighbours().add(room7);
room7.getNeighbours().add(room6);
room7.getNeighbours().add(room9);
room7.getNeighbours().add(room8);
List<Room> path=Path.findPath(room1, room9);
for(Room room:path)
System.out.println("Room:"+room.getId());
}
}
РЕДАКТИРОВАТЬ: небольшая оптимизация: в каждой комнате всегда есть по крайней мере один сосед, а именнономер, откуда мы родом, поэтому не нужно проверять, есть ли соседи.Единственное исключение возможно, когда в лабиринте есть только одна комната, но в этом случае начало и цель совпадают, что уже было проверено ранее.