Menu Close

Randomly Generated Maze

Using a tutorial by FlatTutorials, I created a script that creates a random maze each time the scene is played. The ball is using transform.translate, which I wrote myself. The red box, the end point, was created by a classmate. When the player, the blue ball, makes contact with the red box, it randomly transports the player to a different scene in the game. The timer on top is counting down until when the maze scene will restart. The player must make it to the end before the timer is done, each time they lose, they have to try again with a new maze -frustrating, I know.

Below is the code I used.-

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Maze_Generator : MonoBehaviour {

    [System.Serializable]
    public class Cell
    {
        public bool visited;
        public GameObject north;//1
        public GameObject east;//2
        public GameObject west;//3
        public GameObject south;//4
    }
    public GameObject wall;
    public int xSize = 5;
    public int ySize = 5;
    public float wallLength = 1.0f;
    private Vector3 initialPos;
    private GameObject wallHolder;
    private Cell[] cells;
    private int currentCell = 0;
    private int totalCells;
    private int visitedCells = 0;
    private bool startedBuilding = false;
    private int currentNeighbour = 0;
    private List<int> lastCells; 
    private int backingUp = 0;
    private int wallToBreak = 0;

    void Start () 
    {
        CreateWalls ();
    }

    void CreateWalls ()
    {
        totalCells = xSize * ySize;
        wallHolder = new GameObject ();
        wallHolder.name = Maze;

        initialPos = new Vector3 ((xSize / 2) + wallLength / 2, 0.0f, (ySize / 2) + wallLength / 2);
        Vector3 myPos = initialPos;
        GameObject tempWall;

        //For x Axis
        for(int i = 0; i < ySize; i++)
        {
            for (int j = 0; j <= xSize; j++) 
            {
                myPos = new Vector3 (initialPos.x + (j * wallLength)  wallLength / 2, 0.0f, initialPos.z + (i * wallLength)  wallLength / 2);
                tempWall = Instantiate (wall,myPos,Quaternion.identity) as GameObject;    
                tempWall.transform.parent = wallHolder.transform;
            }
        }
        //For y Axis
        for(int i = 0; i <= ySize; i++)
        {
            for (int j = 0; j < xSize; j++) 
            {
                myPos = new Vector3 (initialPos.x + (j * wallLength), 0.0f, initialPos.z + (i * wallLength)  wallLength);
                tempWall = Instantiate (wall,myPos,Quaternion.Euler(0.0f,90.0f,0.0f)) as GameObject;    
                tempWall.transform.parent = wallHolder.transform;
            }
        }
        CreateCells ();
    }

    void CreateCells ()
    {
        lastCells = new List<int> ();
        lastCells.Clear ();
        GameObject[] allWalls;
        int children = wallHolder.transform.childCount;
        allWalls = new GameObject[children];
        cells = new Cell[xSize * ySize];
        int eastWestProcess = 0;
        int childProcess = 0;
        int termmCount = 0;

        //Gets ALL the children
        for(int i = 0; i < children ; i++)
        {
            allWalls[i] = wallHolder.transform.GetChild(i).gameObject;
        }
        //Assidns walls to the cells
        for(int cellprocess = 0; cellprocess < cells.Length; cellprocess++)
        {
            cells [cellprocess] = new Cell ();
            cells[cellprocess].east = allWalls[eastWestProcess];
            cells[cellprocess].south = allWalls[childProcess+(xSize+1)*ySize];
            if (termmCount == xSize) {
                eastWestProcess += 2;
                termmCount = 0;
            } else
                eastWestProcess++;

            termmCount++;
            childProcess++;
            cells[cellprocess].west = allWalls[eastWestProcess];
            cells[cellprocess].north = allWalls[(childProcess+(xSize+1)*ySize)+xSize1];
        }
        CreateMaze ();
    }

    void CreateMaze()
    {
        while (visitedCells < totalCells) 
        {
            if (startedBuilding) {
                GiveMeNeighbour ();
                if(cells[currentNeighbour].visited == false && cells[currentCell].visited == true)
                {
                    BreakWall ();
                    cells [currentNeighbour].visited = true;
                    visitedCells++;
                    lastCells.Add (currentCell);
                    currentCell = currentNeighbour;
                    if(lastCells.Count > 0)
                    {
                        backingUp = lastCells.Count  1;
                    }
                }

            } 
            else 
            {
                currentCell = Random.Range (0, totalCells);
                cells[currentCell].visited = true;
                visitedCells++;
                startedBuilding = true;
            }
        }
        //Invoke (CreateMaze,0.0f);
    }

    void BreakWall()
    {
        switch (wallToBreak) 
        {
        case 1: Destroy (cells [currentCell].north); break;
        case 2: Destroy (cells [currentCell].east); break;
        case 3: Destroy (cells [currentCell].west); break;
        case 4: Destroy (cells [currentCell].south); break;
        }
    }

    void GiveMeNeighbour()
    {
        totalCells = xSize * ySize;
        int length = 0;
        int[] neighbours = new int[4];
        int[] connectingWall = new int[4];
        int check = 0;
        check = ((currentCell+1) / xSize);
        check -= 1;
        check *= xSize;
        check += xSize; 
        //west
        if (currentCell +1 < totalCells && (currentCell +1) != check)
        {
            if (cells [currentCell + 1].visited == false) 
            {
                neighbours [length] = currentCell + 1;
                connectingWall [length] = 3;
                length++;
            }
        }

        //east
        if (currentCell  1 >= 0 && currentCell != check)
        {
            if (cells [currentCell  1].visited == false) 
            {
                neighbours [length] = currentCell  1;
                connectingWall [length] = 2;
                length++;
            }
        }

        //north
        if (currentCell + xSize < totalCells)
        {
            if (cells [currentCell + xSize].visited == false) 
            {
                neighbours [length] = currentCell + xSize;
                connectingWall [length] = 1;
                length++;
            }
        }

        //south
        if (currentCell  xSize >= 0)
        {
            if (cells [currentCell  xSize].visited == false) 
            {
                neighbours [length] = currentCell  xSize;
                connectingWall [length] = 4;
                length++;
            }
        }
        if (length != 0) {
            int theChosenOne = Random.Range (0, length);
            currentNeighbour = neighbours [theChosenOne];
            wallToBreak = connectingWall [theChosenOne];
        } 
        else 
        {
            if (backingUp > 0) 
            {
                currentCell = lastCells [backingUp];
                backingUp–;
            }
        }

    }
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *