ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi everyone, I'm taking a c++ class, and am working on a project that creates a 3d maze and then works on solving it.
So I made a 3d vector maze of a custom data structure called cube
I've successfully implemented random population of the 3d maze, i'm on the last part of the project which is to solve the maze, the idea is to traverse the maze and leave the coordinates of the path on the stack. I use a different function to organize these into a nice array of points. Anyway my code for solving is this:
When I run the code i get stuck going back and forth after I hit a certain wall, the code returns then when it tries again it gets stuck. The general idea I have is to check right as far as i can, then return and check the other options, if those are exhausted I'll move back one and try all options (depth search).
Code:
working on0 0 0
pushing(0, 0, 0)
working on1 0 0
pushing(1, 0, 0)
working on2 0 0
is a wall
working on2 1 0
is a wall
working on2 1 1
is a wall
working on2 0 1
pushing(2, 0, 1)
working on3 0 1
pushing(3, 0, 1)
working on4 0 1
pushing(4, 0, 1)
working on5 0 1
out of bounds
working on5 1 1
out of bounds
working on5 1 2
out of bounds
working on5 0 2
out of bounds
working on5 0 1
out of bounds
working on4 0 1
I'm thinking I'm probably over-complicating this, but any input on either a more simple algorithm, or pointers on where I've gone wrong, or why this is happening would be greatly appreciated.
Hi, your code is hard to follow.
This seems strange to me:
Code:
working on0 0 0
pushing(0, 0, 0)
working on1 0 0
pushing(1, 0, 0)
working on2 0 0
is a wall
working on2 1 0
is a wall
working on2 1 1
is a wall
working on2 0 1
pushing(2, 0, 1)
How come you get from (1, 0, 0) to (2, 0, 1)?
I have a few suggestions, though:
Code:
find_x = x;
find_y = y;
find_z = z;
I would definitely use an array/vector (a class with an overloaded + operator would be nice, too) for coordinates. Also, i would make an enum for directions
Code:
enum direction {
right = 0,
forward = 1,
up = 2,
left = 3,
backward = 4,
down = 5,
};
also, this way, the direction oposite to dir will be (dir + 3) % 6.
Then I would define steps in these directions, so that step[right] is {1, 0, 0} and so on.
That would allow me to get rid of those 6 ugly if() statements in your code and replace it with a single loop over all directions.
Then the logic would be simple: for each room in the maze, remember whether or not you already visited it and where you came from (direction). loop over all adjacent rooms until you find one you haven't visited yet and move there. If all adjacent rooms have been visited already, go back to the previous room you came from. Repeat until you get either to the finish, or to the starting room and there are no unvisited adjacent rooms, in which case there is no solution.
Recursive functions can solve mazes pretty cleanly. It won't necessarily give you the ideal solution, but it will give you a solution. The logic goes something like:
Code:
function recfunc(x,y,z)
if (haveIBeenHere(x,y,z)) return(0)
if (didIHitAWall(x,y,z)) return(0)
if (amIAtTheEnd(x,y,z)) return(1)
haveIBeenHere(x,y,z)=1
for(ii=-1;ii<=1;ii+=2){
for(jj=-1;jj<=1;jj+=2){
for(kk=-1;kk<=1;kk+=2){
if (recfunc(x+ii,y+jj,z+kk)) then return(1)
}
}
}
return(0)
or if you only want to move in the cardinal directions:
Code:
function recfunc(x,y,z)
if (haveIBeenHere(x,y,z)) return(0)
if (didIHitAWall(x,y,z)) return(0)
if (amIAtTheEnd(x,y,z)) return(1)
haveIBeenHere(x,y,z)=1
for(ii=-1;ii<=1;ii+=2){
if (recfunc(x, y, z+kk)) then return(1)
if (recfunc(x, y+jj,z)) then return(1)
if (recfunc(x+ii,y, z)) then return(1)
}
return(0)
The function will recursively call itself and walk through the maze, ignoring cells it's checked before, and walking backwards through function calls when it hits a dead end or the end of the maze. You would just want to set up an array to record the x,y,z locations when recfunc returns a 1, which will be the path backwards through the maze when you're finally back at the original function call.
Last edited by suicidaleggroll; 11-06-2013 at 10:02 AM.
Thanks for both of you input, I think I have a working solver, yet I'm getting a segmentation fault when I do find the end of the maze.
My code at present:
note I have cout all over for debugging, I put one before I call basically any variable, and when I run the code, I do get a valid path (i've walked through an entire maze) but I get this at the end in the terminal:
Quote:
pushing(1, 4, 4)
*****findpath called
working on2 4 4
checking if end
checking to see if its in bounds
checking for wall
checking if visited
operarting on valid cube
pushing(2, 4, 4)
*****findpath called
working on3 4 4
checking if end
checking to see if its in bounds
checking for wall
checking if visited
operarting on valid cube
pushing(3, 4, 4)
*****findpath called
working on4 4 4
checking if end
is finish
Run_Test_Driver.sh: line 14: 21690 Segmentation fault (core dumped) ./$EXE
Press any key to exit...
As you can see in my code, the last thing it does is return true; I really cant figure out why I'm getting seg-fault. Does anyone have an Idea where this is coming from?
Thank you for your input, it has been very helpful!
-MJ
What's with all of the checks if you've visited the cell? You only need one right at the start of the function, toss all the others. It looks like you're driving yourself into a corner here. What happens when it hits the finish?
The findPath will be true, but so will the Maze.visited since you just set it in findPath. Since you're checking if Maze.visited != true, that if statement will always fail. In fact, every time findPath gets called, the associated index in Maze gets set to true, so that if statement will always fail. You should revisit your logic.
You're also pushing your indices in the wrong spot. Who cares if you're visiting a cell, you only want to know if the cell you're in is on the right track to solving the maze. You need to push the indices as your recursion unwinds with "return true", and the result will be a stack of indices in reverse order to solve the maze (starting with the end, and going back to the start). Otherwise your stack is going to be FULL of dead end paths with incoherent jumps back to previous cells, etc. Please re-read post #3, it was all described there. And maybe remove the stack push and pop until you know the underlying logic is working correctly.
Last edited by suicidaleggroll; 11-07-2013 at 09:23 AM.
Thank you so much, I realized that I wasn't checking all up down left right forward and back, so I added the missing components as well as fixed the issue with the if statements and it works pretty well. Cheers.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.