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);