I'm currently trying to auto-generate a maze of randomly generated room objects that are linked via pointers in 4 directions - n, s, e, and w. I begin at Room *home, and build out with each new room having a 1/3 chance in creating a door in each of the other three directions (it of course has a door back to where it came from). This runs until all "leaves" have three null pointers to the other directions. I believe the map is being created properly, as I am able to "move around" within it using another function (not included below). My question is how can I find the height of this structure. It is essentially a quad-tree. Here is my code for building the maze and attempting to find the height. I get a segmentation fault when executing. If I comment out any three of the four recursive calls in height, it does not fault.
void buildMaze(Room *newRoom, char d)
{
int rando;
Room *last = newRoom;
//coming from south
if(d == 's')
{
newRoom = new Room();
newRoom->southDoor = last;
last->northDoor = newRoom;
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 's');//build north room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'w');//build east room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'e');//build west room
}
//coming from north
else if(d == 'n')
{
newRoom = new Room();
newRoom->northDoor = last;
last->southDoor = newRoom;
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'n');//build south room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'w');//build east room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'e');//build west room
}
//coming from east
else if(d == 'e')
{
newRoom = new Room();
newRoom->eastDoor = last;
last->westDoor = newRoom;
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 's');//build north room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'n');//build south room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'e');//build west room
}
//coming from west
else if(d == 'w')
{
newRoom = new Room();
newRoom->westDoor = last;
last->eastDoor = newRoom;
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 's');//build north room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'n');//build south room
rando = arc4random_uniform(3);
if(rando == 1)
buildMaze(newRoom, 'w');//build east room
}
//home room always has 4 doors
else
{
buildMaze(newRoom, 's');//build north room
buildMaze(newRoom, 'n');//build south room
buildMaze(newRoom, 'w');//build east room
buildMaze(newRoom, 'e');//build west room
}
}
//longest distance from home
int height(Room *r)
{
int n, s, e, w;
if (r == nullptr)
return 0;
else
{
//compute the height of each subtree
n = height(r->northDoor);
s = height(r->southDoor);
e = height(r->eastDoor);
w = height(r->westDoor);
//return the largest tree height
if (n >= s && n >= e && n >= w)
return (n + 1);
else if(s >= n && s >= e && s >= w)
return (s + 1);
else if(e >= n && e >= s && e >= w)
return (e + 1);
else
return (w + 1);
}
}
As Will_Panda says there is infinite recursion because the links back to the room you came from mean you just go round in a recursive loop.
Simplest way to fix is to add a field to you Room
class to indicate that the room has already been visited as part of the height calculation. Then if visited
is false before you start your calculation you can use it to avoid infinite recursion. E.g.
//longest distance from home
int height(Room *r)
{
int n, s, e, w;
if (r == nullptr)
return 0;
else if (r->visited) // already been here
return 0;
else
{
//compute the height of each subtree
r->visited = true;
n = height(r->northDoor);
s = height(r->southDoor);
e = height(r->eastDoor);
w = height(r->westDoor);
//return the largest tree height
if (n >= s && n >= e && n >= w)
return (n + 1);
else if(s >= n && s >= e && s >= w)
return (s + 1);
else if(e >= n && e >= s && e >= w)
return (e + 1);
else
return (w + 1);
}
}
Once you know the height you will have to go through all the rooms again clearing all the visited fields
//clear visited fields
void clear_visited(Room *r)
{
if (r == nullptr)
return;
else if (!r->visited) // already cleared
return;
else
{
r->visited = false;
clear_visited(r->northDoor);
clear_visited(r->southDoor);
clear_visited(r->eastDoor);
clear_visited(r->westDoor);
}
}
Completely untested code.