Search code examples
mazepawn

Maze Generation - Converting From C++


Ok, many of you may not know what Pawn is. I'm converting the source from here http://en.wikipedia.org/wiki/User:Dllu/Maze to work in my SA:MP server. Pawn is a very easy code to understand so don't run because you don't know the language.

For some reason, only the outside padding and first cell (which they should be) are set to be in the maze. So, all the walls are there, and that's good. The problem is that only one cell is in the maze, and that is the starting point.

Please help!


I pasted it on Pastebin because pastebin actually has a pawn syntax. http://pastebin.com/wN6KFyFz


Also, it is supposed to support both backtrack and prim. Both have the same outcome. From what I tested I know that it never reaches the debug prints that look like this ("%i, %i | %x, %x, %x"). Well, it does reach the one in the while(!successful) loop, 1 time or 2-3 every once in a while.


Solution

  • It's not working because you have changed some of the do...while loops in the C++ code to while loops in Pawn, which is not logically equivalent. do...while loops always execute at least once, whereas while loops execute zero or more times.

    For example this code assumes that it will be run at least once:

    do{
        //randomly find a cell that's in the maze
        xcur=rand()%(xsize-2)+1;
        ycur=rand()%(ysize-2)+1;
    }while(!MAZE[xcur][ycur].in ||
        MAZE[xcur][ycur-1].in&&MAZE[xcur][ycur+1].in&&
        MAZE[xcur-1][ycur].in&&MAZE[xcur+1][ycur].in);
    

    If you change that to a while loop then the loop condition will test false (because you start on a cell that's in the maze and isn't surrounded by cells that are) and so the loop will not be entered, xcur and ycur will never change and you will be stuck at the starting location forever!

    If whatever version of Pawn you are using doesn't support do...while loops then you can fake them like this:

    new bool:doOnce;
    doOnce=true;
    while(doOnce||(condition))
    {
        doOnce=false;
        // do stuff...
    }
    

    is the same as

    do
    {
        // do stuff...
    } while(condition)
    

    assuming that evaluating the condition does not have any side effects, like incrementing or assigning variables, or Pawn is able to short-circuit the evaluation when doOnce is true.

    Or else you can do it like this:

    while(true)
    {
        // do stuff....
    
        if(!condition)
            break;
    }