How can i make an entrance and exit in this maze ?

The script build a maze but it’s close i can move the player inside.
I want that each time it’s creating the maze it will create a random 2 empty bricks in the outer square like entrance and exit.

So i want to add some public variable so if i change it’s value to 1 there will be one entrance and one exit. If i will change the value 3 or to 15 so there will be 3 entrances and 3 exits or if i change it to 15 there will be 15 entrances and 15 exits.

This kind of logic or something like that.
And that this entrances and exits will be in a random positions each time i’m running the game.

Another sub question:

I can change now the height and width of the maze. but if i want that all the terrain will be filled with the maze ? for example the terrain resolution is:

Example how the maze looks like now:

Width = 500
Length = 500
Height = 600

So i want that the maze will be automatic all over the terrain area.
The Height should not be 600 but the maze size should be on the terrain size.

// mazegen.cs
// remember you can NOT have even numbers of height or width in this style of block maze
// to ensure we can get walls around all tunnels...  so use 21 x 13 , or 7 x 7 for examples.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class MazeGenerator : MonoBehaviour
{
    public int width, height;
    public Material brick;
    private int[,] Maze;
    private Stack<Vector2> _tiletoTry = new Stack<Vector2>();
    private List<Vector2> offsets = new List<Vector2> { new Vector2(0, 1), new Vector2(0, -1), new Vector2(1, 0), new Vector2(-1, 0) };
    private System.Random rnd = new System.Random();
    private Vector2 _currentTile;
    public static string MazeString;

    public Vector2 CurrentTile
    {
        get { return _currentTile; }
        private set
        {
            if (value.x < 1 || value.x >= this.width - 1 || value.y < 1 || value.y >= this.height - 1)
            {
                throw new ArgumentException("Width and Height must be greater than 2 to make a maze");
            }
            _currentTile = value;
        }
    }
    private static MazeGenerator instance;
    public static MazeGenerator Instance
    {
        get { return instance; }
    }
    void Awake() { instance = this; MakeBlocks(); }
    // end of main program
    // ============= subroutines ============
    void MakeBlocks()
    {

        Maze = new int[width, height];
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                Maze[x, y] = 1;
            }
        }
        CurrentTile = Vector2.one;
        _tiletoTry.Push(CurrentTile);
        Maze = CreateMaze();  // generate the maze in Maze Array.
        GameObject ptype = null;
        for (int i = 0; i <= Maze.GetUpperBound(0); i++)
        {
            for (int j = 0; j <= Maze.GetUpperBound(1); j++)
            {
                if (Maze[i, j] == 1)
                {
                    MazeString = MazeString + "X";  // added to create String
                    ptype = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    ptype.transform.position = new Vector3(i * ptype.transform.localScale.x, 0, j * ptype.transform.localScale.z);

                    if (brick != null) { ptype.GetComponent<Renderer>().material = brick; }
                    ptype.transform.parent = transform;
                }
                else if (Maze[i, j] == 0)
                {
                    MazeString = MazeString + "."; // added to create String
                }
            }
            MazeString = MazeString + "

"; // added to create String
}
print(MazeString); // added to create String
}
// =======================================
public int[,] CreateMaze()
{

        //local variable to store neighbors to the current square as we work our way through the maze
        List<Vector2> neighbors;
        //as long as there are still tiles to try
        while (_tiletoTry.Count > 0)
        {
            //excavate the square we are on
            Maze[(int)CurrentTile.x, (int)CurrentTile.y] = 0;
            //get all valid neighbors for the new tile
            neighbors = GetValidNeighbors(CurrentTile);
            //if there are any interesting looking neighbors
            if (neighbors.Count > 0)
            {
                //remember this tile, by putting it on the stack
                _tiletoTry.Push(CurrentTile);
                //move on to a random of the neighboring tiles
                CurrentTile = neighbors[rnd.Next(neighbors.Count)];
            }
            else
            {
                //if there were no neighbors to try, we are at a dead-end toss this tile out
                //(thereby returning to a previous tile in the list to check).
                CurrentTile = _tiletoTry.Pop();
            }
        }
        print("Maze Generated ...");
        return Maze;
    }

    // ================================================
    // Get all the prospective neighboring tiles "centerTile" The tile to test
    // All and any valid neighbors</returns>
    private List<Vector2> GetValidNeighbors(Vector2 centerTile)
    {
        List<Vector2> validNeighbors = new List<Vector2>();
        //Check all four directions around the tile
        foreach (var offset in offsets)
        {
            //find the neighbor's position
            Vector2 toCheck = new Vector2(centerTile.x + offset.x, centerTile.y + offset.y);
            //make sure the tile is not on both an even X-axis and an even Y-axis
            //to ensure we can get walls around all tunnels
            if (toCheck.x % 2 == 1 || toCheck.y % 2 == 1)
            {

                //if the potential neighbor is unexcavated (==1)
                //and still has three walls intact (new territory)
                if (Maze[(int)toCheck.x, (int)toCheck.y] == 1 && HasThreeWallsIntact(toCheck))
                {

                    //add the neighbor
                    validNeighbors.Add(toCheck);
                }
            }
        }
        return validNeighbors;
    }
    // ================================================
    // Counts the number of intact walls around a tile
    //"Vector2ToCheck">The coordinates of the tile to check
    //Whether there are three intact walls (the tile has not been dug into earlier.
    private bool HasThreeWallsIntact(Vector2 Vector2ToCheck)
    {

        int intactWallCounter = 0;
        //Check all four directions around the tile
        foreach (var offset in offsets)
        {

            //find the neighbor's position
            Vector2 neighborToCheck = new Vector2(Vector2ToCheck.x + offset.x, Vector2ToCheck.y + offset.y);
            //make sure it is inside the maze, and it hasn't been dug out yet
            if (IsInside(neighborToCheck) && Maze[(int)neighborToCheck.x, (int)neighborToCheck.y] == 1)
            {
                intactWallCounter++;
            }
        }
        //tell whether three walls are intact
        return intactWallCounter == 3;
    }

    // ================================================
    private bool IsInside(Vector2 p)
    {
        //return p.x >= 0  p.y >= 0  p.x < width  p.y < height;
        return p.x >= 0 && p.y >= 0 && p.x < width && p.y < height;
    }
}

Answering to your terrain sized maze question, you could just get terrains size parameters and assign them to your maze height and width (Assuming 1 unit of your maze matches 1 unit of unity):

//Checking if the terrain size is even, so if it's not the value becomes even
width = (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x % 2 == 0 ? (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x : (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x + 1;
		heigth = (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z % 2 == 0 ? (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z : (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z + 1;

For the main question, you should define some guidelanes. What do you want your maze behaviour to be?

For example:

-The entrance and exit must be on the outside.

-The entrance and exit must be accesible (have an adjacent nonwall tile).

-The entrance and exit can’t be near (define a minimun distance between
them).

-If more than one pair of entrance and exit exists, check that entrances and
exists don’t match in position.

With defined guidelines it should be easy to achieve what you are looking for, just try to reflect them into your code after the maze creation algorithm has finished.