You are traversing a graph. The key points here are:
- You can get to a certain "room" in more than one way; so you need to keep track of which rooms you already visited so you don't try to follow their exits again.
- Since each room has multiple exits, you need to visit one of them at time while remembering to come back and try the others later.
One simple way is to use recursion to visit all the exits, while storing some flag on rooms you already visited:
var visitRoom = function(rooms, roomId) {
if (roomId === -1)
return;
var room = rooms[roomId];
if (room.visited)
return;
room.visited = true;
doSomethingWithRoom(room);
visitRoom(rooms, room.n);
visitRoom(rooms, room.e);
visitRoom(rooms, room.s);
visitRoom(rooms, room.w);
visitRoom(rooms, room.u);
visitRoom(rooms, room.d);
};
visitRoom(rooms, 0); // assuming you're starting at the first room
The problems here are:
Storing
room.visited
is a little messy, since it pollutes the original data with intermediate state required by the traversal algorithm.This code assumes each room's ID is equal to its index in the array. If this is not the case, you'd want to find a way to get a room by its ID. A map between room IDs and the room objects is more useful in this case than an array.
A recursive approach would exhaust the stack memory in large-enough maps. This can be remedied by using an iterative approach where instead of visiting a room by recursion, you add its ID to a list of rooms-to-visit, then continually visit the first room in the list until it's empty. Keeping a list of unvisited rooms takes less memory than storing the stack frame for the recursive call.
Here's another approach, which addresses these issues:
var visitAll = function(rooms) {
var toVisit = [0];
var visited = {};
while (toVisit.length > 0) {
var roomId = toVisit.pop();
var room = findRoomById(rooms, roomId);
doSomethingWithRoom(room);
visited[roomId] = true;
["n", "s", "e", "w", "u", "d"].forEach(function(exit) {
var exitId = room[exit];
if (exitId !== -1 && !visited[exitId])
toVisit.push(exitId);
});
}
}
var findRoomById = function(rooms, roomId) {
// do whatever you need to find the room with the correct ID
return rooms[roomId];
}
var doSomethingWithRoom = function(room) {
// do what you want here; this will be called once per visited room
}
visitAll(rooms);
If you also want to keep track of the spatial coordinates of each room, you could do that too by assigning each room its location when you first encounter it, based on the coordinates of the previous room and the direction of the exit you followed.