Java 在房间数组列表中递归搜索路径

Java 在房间数组列表中递归搜索路径,java,arraylist,path-finding,Java,Arraylist,Path Finding,我试图在一个有房间的地牢里找到一条路,房间是通过门连接起来的。 从一个房间到另一个房间总是只有一种方式。 有人能帮我建一条路吗?我已经研究了路径搜索算法,但是对于这个例子来说它们太复杂了,因为只有一条可能的路径,因此不需要增加房间的重量 这是我正在使用的房间对象: public Room(int id, Tile centerTile, ArrayList<Room> neighbours, ArrayList<Door> doors) id = unique r

我试图在一个有房间的地牢里找到一条路,房间是通过门连接起来的。 从一个房间到另一个房间总是只有一种方式。 有人能帮我建一条路吗?我已经研究了路径搜索算法,但是对于这个例子来说它们太复杂了,因为只有一条可能的路径,因此不需要增加房间的重量

这是我正在使用的房间对象:

public Room(int id, Tile centerTile, ArrayList<Room> neighbours, ArrayList<Door> doors) 

  id = unique room id

  centerTile = center of the room.

  neighbours = list of neighbouring rooms

  doors = list of doors leading to the neighbouring rooms
公共房间(内部id、瓷砖中心瓷砖、ArrayList邻居、ArrayList门)
id=唯一的房间id
中心瓷砖=房间的中心。
邻居=相邻房间的列表
门=通向相邻房间的门列表
这些房间存储在一个名为explored rooms的Arraylist中

这是我目前得到的,但它不起作用

package pathing;

import room.Room;
import room.RoomUtils;

import java.util.ArrayList;
import java.util.Iterator;

public class Path {

public static ArrayList<Room> findPath(Room start, Room target) {

    ArrayList<Room> frontier = new ArrayList<>();
    ArrayList<Node> visited = new ArrayList<>();
    ArrayList<Room> path = new ArrayList<>();

    frontier.add(RoomUtils.getRoomById(start.getId()));
    visited.add(new Node(RoomUtils.getRoomById(start.getId()), null));

    if (start.equals(target)) {
        path.add(RoomUtils.getRoomById(start.getId()));
    } else {
        Iterator frontierIterator = frontier.listIterator();
        while (frontierIterator.hasNext()) {
            Room front = (Room) frontierIterator.next();
            front = RoomUtils.getRoomById(front.getId());
            if (front.getNeighbours().size() > 0) {
                for (Room room : front.getNeighbours()) {
                    if (room.equals(target)) {
                        frontier.clear();
                        visited.add(new Node(RoomUtils.getRoomById(room.getId()), RoomUtils.getRoomById(front.getId())));
                        frontierIterator = frontier.listIterator();
                    } else {
                        frontier.remove(RoomUtils.getRoomById(front.getId()));
                        visited.add(new Node(RoomUtils.getRoomById(room.getId()), RoomUtils.getRoomById(front.getId())));
                        frontierIterator = frontier.listIterator();
                    }
                }
            }
        }

        Node startNode = visited.get(0);
        Node backtrackNode = getFrom(visited, target);

        if (backtrackNode != null && backtrackNode.getCurrent() != null) {
            path.add(backtrackNode.getCurrent());
        }

        while (backtrackNode != null && backtrackNode.getFrom() != null && !backtrackNode.equals(startNode)) {
            path.add(backtrackNode.getFrom());
            backtrackNode = getFrom(visited, backtrackNode.getFrom());
        }
    }
    return path;
}

private static Node getFrom(ArrayList<Node> nodes, Room from) {
    for (Node node : nodes) {
        if (node.getCurrent().equals(from)) {
            return node;
        }
    }
    return null;
}

private static class Node {
    private final Room current;
    private final Room from;

    public Node(Room current, Room from) {
        this.current = current;
        this.from = from;
    }

    public Room getCurrent() {
        return current;
    }

    public Room getFrom() {
        return from;
    }
}
包路径;
进口房。进口房;
导入room.RoomUtils;
导入java.util.ArrayList;
导入java.util.Iterator;
公共类路径{
公共静态ArrayList findPath(文件室开始,文件室目标){
ArrayList frontier=新的ArrayList();
ArrayList visited=新建ArrayList();
ArrayList路径=新建ArrayList();
add(RoomUtils.getRoomById(start.getId());
add(新节点(RoomUtils.getRoomById(start.getId()),null));
如果(开始等于(目标)){
add(RoomUtils.getRoomById(start.getId());
}否则{
迭代器frontierIterator=frontier.listIterator();
while(frontierIterator.hasNext()){
Room front=(Room)frontierIterator.next();
front=RoomUtils.getRoomById(front.getId());
if(front.getneights().size()>0){
用于(房间:front.getneights()){
如果(房间等于(目标)){
边界。清除();
add(新节点(RoomUtils.getRoomById(room.getId()),RoomUtils.getRoomById(front.getId()));
frontierIterator=frontier.listIterator();
}否则{
remove(RoomUtils.getRoomById(front.getId());
add(新节点(RoomUtils.getRoomById(room.getId()),RoomUtils.getRoomById(front.getId()));
frontierIterator=frontier.listIterator();
}
}
}
}
节点startNode=visted.get(0);
节点backtrackNode=getFrom(已访问,目标);
if(backtrackNode!=null&&backtrackNode.getCurrent()!=null){
add(backtrackNode.getCurrent());
}
while(backtrackNode!=null&&backtrackNode.getFrom()!=null&&backtrackNode.equals(startNode)){
add(backtrackNode.getFrom());
backtrackNode=getFrom(已访问,backtrackNode.getFrom());
}
}
返回路径;
}
私有静态节点getFrom(ArrayList节点、房间from){
用于(节点:节点){
if(node.getCurrent().equals(from)){
返回节点;
}
}
返回null;
}
私有静态类节点{
私人最终房间电流;
私人最终房间从;
公共节点(房间当前、房间起始){
这个电流=电流;
this.from=from;
}
公共休息室{
回流;
}
公共休息室{
返乡;
}
}

}

您问题的标题包含“递归”,因此我寻找递归解决方案。 对于每个房间,你可以说:如果我的一个邻居房间通向目标房间,那么我也是这条路的一部分。当你的邻居中没有一个通向目标的时候,你也不是这条路的一部分

为了使它递归,我创建了一个新方法,它从当前房间开始。 已访问房间的总体路径和列表定义为类变量,因此在所有调用
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());
        }
}
包路径;
导入java.util.ArrayList;
导入java.util.List;
进口房。进口房;
公共类路径{
//要检测环路的所有已访问房间的列表
访问列表=新建ArrayList();
//从起点到当前房间的路径
列表路径=新的ArrayList();
房间目标;
布尔路径发现=false;
公共无效检查室(当前房间){
如果(路径发现){
返回;
}
if(已访问。包含(当前))
{
//我们以前来过这里,我们检测到一个循环
返回;
}
添加路径(当前);
已访问。添加(当前);
如果(当前等于(目标)){
pathFound=true;
}否则{
//总是有邻居(至少是我们住的那个房间)
for(房间:current.getNeights()){
检查室;
如果(路径发现){
返回;
}
}
//所有的邻居都没有成功
移除路径(当前);
}
}
公共静态列表findPath(文件室开始,文件室目标){
路径p=新路径();
p、 目标=目标;
p、 检查室(开始);
返回p.path;
}
公共静态void main(字符串参数[])
{
//      2 - 3 - 4
//      |   |
//      1 - 5
//      |
//      6 - 7 - 9
//          |
//          8
Room room1=新房间(1,新阵列列表());
Room room2=新房间(2,新阵列列表());
Room room3=新房间(3,新阵列列表());
Room room4=新房间(4,新阵列列表());
Room room5=新房间(5,新阵列列表());
Room room6=新房间(6,新阵列列表());
Room room7=新房间(7,新阵列列表());
Room room8=新房间(8,新阵列列表());
Room room9=新房间(9,新阵列列表());
room1.getneights().add(room2);
room1.getneights().add(room5);
room1.getneights().add(room6);
room2.getneights().add(room1);
room2.getneights().add(room3);