2

I am currently generating a random maze in Unity using prim's algorithm.

This is what the maze looks like if I run the game.

http://i1.ytimg.com/vi/ucWX34Vrel8/maxresdefault.jpg

This is what I want the maze to look like.

http://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/MAZE_30x20_Prim.ogv/220px--MAZE_30x20_Prim.ogv.jpg

The difference is that the first one has the corner's of white squares touching while the second one has space in between the white squares at all times.

This is the code which controls the visual creation of the maze:

void FindNext(){
    //We create an empty Transform variable
    // to store the next cell in.
    Transform next;
    //List for the current cell's adjacents
    List<Transform> curAdjacents;
    //List for an element's adjacents
    List<Transform> eleAdjacents;
    //Number variable for while loop
    int num = 1;
    //Perform this loop 
    // While:
    //  The proposed next gameObject's AdjacentsOpened
    //   is less than or equal to 2.
    //   This is to ensure the maze-like structure.
    do{
        //We'll initially assume that each sub-list of AdjSet is empty
        // and try to prove that assumption false in the for loop.
        // This boolean value will keep track.
        bool empty = true;
        //We'll also take a note of which list is the Lowest,
        // and store it in this variable.
        int lowestList = 0;
        for(int i = 0; i < 10; i++){
            //We loop through each sub-list in the AdjSet list of
            // lists, until we find one with a count of more than 0.
            // If there are more than 0 items in the sub-list,
            // it is not empty.
            //We then stop the loop by using the break keyword;
            // We've found the lowest sub-list, so there is no need
            // to continue searching.
            lowestList = i;
            if(AdjSet[i].Count > 0){
                empty = false;
                break;
            }
        }
        //There is a chance that none of the sub-lists of AdjSet will
        // have any items in them.
        //If this happens, then we have no more cells to open, and
        // are done with the maze production.
        if(empty){ 
            //If we finish, as stated and determined above,
            // display a message to the DebugConsole
            // that includes how many seconds it took to finish.
            Debug.Log("We're Done, "+Time.timeSinceLevelLoad+" seconds taken"); 
            //Then, cancel our recursive invokes of the FindNext function,
            // as we're done with the maze.
            //If we allowed the invokes to keep going, we will receive an error.
            CancelInvoke("FindNext");
            //Set.Count-1 is the index of the last element in Set,
            // or the last cell we opened.
            //This will be marked as the end of our maze, and so
            // we mark it red.
            Set[Set.Count-1].renderer.material.color = Color.red;
            //Every cell in the grid that is not in the set
            // will be moved one unit up and turned black.
            // (I changed the default color from black to clear earlier).
            // If you instantiate a FirstPersonController in the maze now,
            // you can actually try walking through it.
            // It's really hard.
            foreach(Transform cell in Grid){
                if(!Set.Contains(cell)){
                    cell.Translate(Vector3.up); 
                    cell.renderer.material.color = Color.black;
                }
            }
            return;
        }
        //If we did not finish, then:
        // 1. Use the smallest sub-list in AdjSet
        //     as found earlier with the lowestList
        //     variable.
        // 2. With that smallest sub-list, take the first
        //     element in that list, and use it as the 'next'.
        next = AdjSet[lowestList][0];
        curAdjacents = next.GetComponent<CellScript>().Adjacents;
        //Since we do not want the same cell in both AdjSet and Set,
        // remove this 'next' variable from AdjSet.
        AdjSet[lowestList].Remove(next);

        //This is code I'm trying to use to solve the issue
        //When I run it though it makes all but the first and last,
        //square white. It is supposed to NOT break if one of the current,
        //cell's adjacents cells has an adjacent cell that has already,
        //been made white. I don't know what's wrong with this code.
        //foreach(Transform element in curAdjacents){
            //eleAdjacents = element.GetComponent<CellScript>().Adjacents;
            //foreach(Transform elem in eleAdjacents){
                //if(Set.Contains(elem)){
                    //continue;
                //}
                //else{
                    //Debug.Log("BREAK!");
                    //num = 0;
                    //break;
                //}
            //}
        //}
    }while(next.GetComponent<CellScript>().AdjacentsOpened >= 2 && num == 1);
    //The 'next' transform's material color becomes white.
    next.renderer.material.color = Color.white;
    //We add this 'next' transform to the Set our function.
    AddToSet(next);
    //Recursively call this function as soon as this function
    // finishes.
    Invoke("FindNext", 0);
}

Any solutions are welcome, whether they be small changes or a complete reworking of all the code. If you don't know how to fix the code but you know how to make a maze the way I desire using prim's algorithm please share it.

jordanhill123
  • 4,142
  • 2
  • 31
  • 40
  • Possible duplicate of [Implementing a randomly generated maze using Prim's Algorithm](http://stackoverflow.com/questions/29739751/implementing-a-randomly-generated-maze-using-prims-algorithm) – RaidenF Jan 08 '16 at 20:11
  • Tried this? If you wan, I can make that F#, C# for you. http://stackoverflow.com/questions/29739751/implementing-a-randomly-generated-maze-using-prims-algorithm – RaidenF Jan 08 '16 at 20:11

2 Answers2

0

In fact, I would guess you are almost there, you just have to include artificial space between the nodes. I would guess that if you are operating on a graph like

ooo
ooo
ooo

where o represent nodes, the actually generated paths in the maze should look like

o-o-o
| | |
o-o-o
| | |
o-o-o

which means that some more space has to be included in the actual maze.

Codor
  • 17,447
  • 9
  • 29
  • 56
  • Ok. How would you resolve to implement this? The way the maze generation works I basically change the color of the current cell's cube in the game. If there are spaces in between how will I change these too? I am using a weight system to determine which block is the next to become white, so the program has no idea which direction it has just gone in. I don't know how to tell it to push the block it passed as well. I've seen implementations of mazes where they create mazes by breaking down walls between nodes which would work with what you say but that isn't how my maze works. Thoughts? – Portable_Hobbit Jul 11 '14 at 22:15
0

Ok, Im going to try and explain this logic using a bunch of ascii pictures because I’m not so hot with words.

Say you start with a maze that looks something like:

...X..
.X.X.X
X....X
X.X.X.
X.X...
...XXX

Where "."s are the travel-able path and "X"s are walls. Assuming that your starting maze is an array, to get to a maze where you get nice separation, you go “block by block” and construct “super blocks” and slot them into a larger array. In this example, the block in the upper left corner would look, up, down, left, and right to see where its neighbor travelable were. It the then construct a “superblock” like:

XXX
X..
X.X

Which has the assumption that “corners” will be walls. After its constructed, it slots itself into the upper left part of the larger array. Likewise, the second block will construct something like:

XXX
...
XXX

And then slot it self into the second position in the upper left. Depending on how you want it to function, it could overlap the first block by one space to keep the stretching down. At this point your larger array would look like (where [] is empty/unassigned yet):

XXXXXX[][][][][]
X.....[][][][][]
X.XXXX[][][][][]
[][][][][][][][]
[][][][][][][][]

This goes on, each block taking a look around itself, making a super block, and setting itself into the large array until you get something like:

XXXXXXXXXXXXXXXXXX
X.......XXXXX.....
X.XXXXX.XXXXX.XXXX
XXXXXXX.XXXXX.XXXX
XXXX..........XXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X 
XXXX.XXXXX.......X
XXXX.XXXXXXXXXXXXX
XXXX.XXXXXXXXXXXXX
........XXXXXXXXXX
XXXXXXXXXXXXXXXXXX
Marky
  • 175
  • 1
  • 10