I figured it'd be easier to write the code first in GM, then once it works convert it to C++ (since I'm more familiar with GML than C++). But it's not working right.
I'm trying to use the Pledge algorithm (this one). That is, the computer should move in a random direction at first. When it hits a wall, it should follow that wall (i.e. keep it on the left or right) until it's turned back in the original direction it was moving, then continue on in a straight line again. It's basically a modification of the Wall Follower that allows for disjointed walls (which I'll have most of the time). It seems to work at first, but then gets stuck in places it shouldn't and goes into an infinite loop.
The code is below. We have a C++ structure to simulate stacks, so they behave exactly like GM's stacks; there's also a structure for points, which I'm simulating here with ds_lists, hence the _c suffix on my stack method calls (custom scripts to create the coordinate list and push it onto the stack). We're supposed to return a stack filled with the sequence of positions to follow to solve the maze--in other words, the resulting path. If there's no solution (which my algorithm can determine if it returns to the original start point), we are supposed to output that ("No solution") and nothing more.
In my implementation, I'm using the array values 0=wall, 1=free space, 2=free space that's been traversed already (I thought it might be useful information at some point). [i,j] is the current position being checked. xdir and ydir represent directions (+1 means right/down, -1 means left/up, and 0 means don't move on that axis). fx and fy are the offsets of the space to check for a wall when following a wall (i.e. where the "right side" is relative to the current direction). fxd and fyd store the original direction of motion before following begins (when this is the same as the current direction, stop following the walls). turns represents the number of turns we've made while following. If this is a multiple of 4, we've turned 360-degrees and are now facing our original direction. following is simply a flag to determine whether we should be following the wall or just moving straight.
moves=ds_stack_create();
ds_stack_push_c(moves,1,1); /* Add the initial position, (1,1), to the stack. */
maze[1,1]=2;
xdir=0;
ydir=1;
i=1;
j=1;
fx=0;
fy=0;
fxd=0;
fyd=0;
turns=0;
following=0;
while (i!=20 && j!=20) {
if (!following) {
if (maze[i+xdir, j+ydir]!=0) {
i+=xdir;
j+=ydir;
}
else {
following=1;
fx=xdir;
fy=ydir;
fxd=xdir;
fyd=ydir;
turns+=1;
if (xdir!=0) { xdir=0; }
else { xdir=ydir; }
if (ydir!=0) { ydir=0; }
else { ydir=-fx; }
if (maze[i+xdir, j+ydir]!=0) {
i+=xdir;
j+=ydir;
}
}
}
else {
if (maze[i+xdir, j+ydir]==0) {
fx=xdir;
fy=ydir;
if (xdir!=0) { xdir=0; }
else { xdir=ydir; }
if (ydir!=0) { ydir=0; }
else { ydir=-fx; }
if (maze[i+xdir, j+ydir]!=0) {
i+=xdir;
j+=ydir;
}
turns+=1;
}
else if (maze[i+xdir, j+ydir]!=0) {
i+=xdir;
j+=ydir;
}
else if (maze[i+fx, j+fy]!=0) {
fx=-xdir;
fy=-ydir;
if (xdir!=0) { xdir=0; }
else { xdir=-ydir; }
if (ydir!=0) { ydir=0; }
else { ydir=-fx; }
if (maze[i+xdir][j+ydir]!=0) {
i+=xdir;
j+=ydir;
}
turns-=1;
}
}
if (xdir==fxd && ydir==fyd) {
following=0;
turns=0;
}
if (i==1 && j==1 && (turns mod 4)==0) { show_message("ESCAPE IS IMPOSSIBLE"); ds_stack_destroy(moves); return -1; }
ds_stack_push_c(moves,i,j);
maze[i, j]=2;
}
return moves;
}It seems like it should work to me, but it keeps going into an infinite loop. Upon debugging, I've found that it'll fall into loops in some paths, which shouldn't happen with this algorithm. Any help?
-IMP
Edited by IceMetalPunk, 10 February 2011 - 10:59 PM.











