5

Ok so I have been trying for the past few weeks to create a rogue like game, what I am stuck on right now, is connecting rooms in a dungeon with hallways. Keep in mind this is all in C, and I am using ncurses. So what I have been trying to do so far, is to run Dijkstra's algorithm from Door A to Door B recording previous nodes and then backtracking this set of previous nodes to get the actual path. There is a problem with my algorithm at the moment, the steps I took to debug it was to translate the code to Java, but the algorithm worked perfectly . Now that I told you that let me give you the actual problem, here is the output of the min path of a 10 by 10 grid without any walls. This is a list of previous nodes visited. (y x) is the origin.

(y x)  (1 1)  (0 1)  (1 3)  (0 3)  (1 5)  (0 5)  (1 7)  (0 7)  (1 9)
(0 0)  (2 1)  (0 2)  (2 3)  (0 4)  (2 5)  (0 6)  (2 7)  (0 8)  (2 9)
(1 0)  (3 1)  (1 2)  (3 3)  (1 4)  (3 5)  (1 6)  (3 7)  (1 8)  (3 9)
(2 0)  (4 1)  (2 2)  (4 3)  (2 4)  (4 5)  (2 6)  (4 7)  (2 8)  (4 9)
(3 0)  (5 1)  (3 2)  (5 3)  (3 4)  (5 5)  (3 6)  (5 7)  (3 8)  (5 9)
(4 0)  (6 1)  (4 2)  (6 3)  (4 4)  (6 5)  (4 6)  (6 7)  (4 8)  (6 9)
(5 0)  (7 1)  (5 2)  (7 3)  (5 4)  (7 5)  (5 6)  (7 7)  (5 8)  (7 9)
(6 0)  (8 1)  (6 2)  (8 3)  (6 4)  (8 5)  (6 6)  (8 7)  (6 8)  (8 9)
(7 0)  (9 1)  (7 2)  (9 3)  (7 4)  (9 5)  (7 6)  (9 7)  (7 8)  (9 9)
(8 0)  (10 1) (8 2)  (10 3) (8 4)  (10 5) (8 6)  (10 7) (8 8)  (10 9)

As you can see, on row 0, column 1, the previous node should be (0 0), and not (1 1). EDIT(I am adding my new bfs instead of the dijkstra)

eq(q,startU);
/*while there are elements in the q*/
while(dq(q,&u))
{

    uX = u[1];
    uY = u[0];



    /*break if at the end*/
    if(uX == xEnd && uY == yEnd)
    {
        break;
    }
    seen[uY][uX]=1;

    /*Neighbours around the current cell*/
    for(i=0;i<4;++i)
    {

        vX = uX + neighbours[i][1];
        vY = uY + neighbours[i][0];
        if(!bounds(vX,vY)||seen[vY][vX])
        {
            continue;
        }

        c=(char)mvinch(vY,vX);

        if(c == '+'||c=='|'||c=='-'||c=='.')
        {
            continue;
        }

        p->prev[vY][vX][1]=uX;
        p->prev[vY][vX][0]=uY;

        u[0]=vY;
        u[1]=vX;

        /*enqueue*/
        eq(q,u);


    }
}
ultrainstinct
  • 255
  • 4
  • 15
  • 5
    On an unrelated note: You don't need Dijkstra for unweighted graphs. You can just use breadth-first search and save one log-factor of runtime. – Niklas B. Mar 09 '14 at 00:08
  • On another unrelated note: your X and Y go in different orders in different places (alphabet order, lines of code, array indices, array dimensions, etc.). This requires a considerable amount of attention to get right. Try naming your axes something other. Perhaps "row" and "col" (short for "column") are good candidates. – Gassa Mar 09 '14 at 00:22
  • 2
    You haven't given us [enough to reproduce the problem](http://www.sscce.org). What happens if you run it under a debugger on a 3x3 grid? – Beta Mar 09 '14 at 00:51
  • I just posted a 10 by 10 grid with the same problem, but this problem persists throughout all NXM grids. So what it seems like is that it works for two columns at a time. – ultrainstinct Mar 09 '14 at 01:05
  • Your code looks good - there are no easily detectable bugs - so if you want help, you should make it possible to [reproduce the problem](http://stackoverflow.com/questions/22276738/dijkstra-path-reconstruction#comment33840984_22276738). Also, please replace 10x10 by 3x3 or 3x2. – anatolyg Mar 09 '14 at 11:03
  • I edited my post to add the bfs version of this without the minpath, and instead of the minpath problem I will show the p->prev problem. – ultrainstinct Mar 09 '14 at 19:35
  • The code has a problem but works perfectly when translated to JAVA ? – user568109 Mar 10 '14 at 15:41
  • @Raditzan do not start new questions about the same issue... if your Question is not yet solved enough then do not check answer as done. if you still have issues the problem is most likely in your eq function. If the point/node/stack Dijkstra is too hard to code for you try the map version first (no stack you just fill 2D array) – Spektre Mar 18 '14 at 08:28
  • It is solved. I changed my stack and queue from an array based one to a pointer based one, so everything is fine. – ultrainstinct Mar 19 '14 at 07:14

2 Answers2

2

1.what is the input array looks like

  • how it is initiated
  • what value is space
  • what value is wall
  • what value is door or opening in wall (start-end points for your path)

2.conditions (if)

  • some compilers do not doing computation priorities for boolean operators correctly
  • try to add () where they should be ...

    //if(uX == xEnd && uY == yEnd)
    if((uX==xEnd)&&(uY==yEnd))
    

3.neighbour constrains

  • you are ignoring neighbours outside range x: < 0,70 ) y: < 0,150 )
  • should not be that upper limit replaced by your room/maze size?
  • if your room is smaller then the path can go the wrong way around your room ...
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • I just edited a lot of the algorithm and showed the problem with the prev array, which in reality is the only thing I need, so I got rid of the minpath and am using a bfs. – ultrainstinct Mar 09 '14 at 19:42
  • 1.try use if((c == '+')||(c=='|')||(c=='-')||(c=='.')) 2.are you sure you have no bug on back-tracing the que? 3.you wrote that you debugging it by converting to JAVA what IDE are you using for the real App ? have you trace/breakpoint it in it? It is not a good idea to debug code on other compiler and then use the code on the original and assume that it all works... – Spektre Mar 10 '14 at 08:00
1

I don't know the rest of your code so here is my diagnosis. See the pattern in your output:

X
|   (y x)  (1 1)  (0 1)  (1 3)  (0 3)  (1 5)  (0 5)  (1 7)  (0 7)  (1 9)
|   (0 0)  (2 1)  (0 2)  (2 3)  (0 4)  (2 5)  (0 6)  (2 7)  (0 8)  (2 9)
V   (1 0)  (3 1)  (1 2)  (3 3)  (1 4)  (3 5)  (1 6)  (3 7)  (1 8)  (3 9)
    (2 0)  (4 1)  (2 2)  (4 3)  (2 4)  (4 5)  (2 6)  (4 7)  (2 8)  (4 9)
    (3 0)  (5 1)  (3 2)  (5 3)  (3 4)  (5 5)  (3 6)  (5 7)  (3 8)  (5 9)
    (4 0)  (6 1)  (4 2)  (6 3)  (4 4)  (6 5)  (4 6)  (6 7)  (4 8)  (6 9)
    (5 0)  (7 1)  (5 2)  (7 3)  (5 4)  (7 5)  (5 6)  (7 7)  (5 8)  (7 9)
    (6 0)  (8 1)  (6 2)  (8 3)  (6 4)  (8 5)  (6 6)  (8 7)  (6 8)  (8 9)
    (7 0)  (9 1)  (7 2)  (9 3)  (7 4)  (9 5)  (7 6)  (9 7)  (7 8)  (9 9)
    (8 0)  (10 1) (8 2)  (10 3) (8 4)  (10 5) (8 6)  (10 7) (8 8)  (10 9)

Traversing top to bottom from in a given column, y increases first and x increases only after the beginning of next column.

Also at the top line of your code

eq(q,startU);
/*while there are elements in the q*/

So based on the output and your code it does not seem like you are doing graph taversal. What you are doing is processing the points in a queue with increasing y in inner loop and x in outer loop. You are processing the data with queue traversal, not with graph traversal.

user568109
  • 47,225
  • 17
  • 99
  • 123