예제 #1
0
        public void ExecuteGeneration(Transform parentObject)
        {
            GameObject mazeObject = new GameObject("Maze");

            mazeObject.transform.parent = parentObject;

            if (LevelData.RoomsCount >= (LevelData.MazeSize.x * 2) * (LevelData.MazeSize.y * 2) * 0.75f)
            {
                _fixedRoomsCount = Mathf.RoundToInt((LevelData.MazeSize.x * 2) * (LevelData.MazeSize.y * 2) * 0.75f);
            }

            else
            {
                _fixedRoomsCount = LevelData.RoomsCount;
            }

            _gridX = Mathf.RoundToInt(LevelData.MazeSize.x);
            _gridY = Mathf.RoundToInt(LevelData.MazeSize.y);

            bool isValid = false;
            int  x       = 0;

            while (!isValid)
            {
                x++;
                GenerateRooms();
                isValid = SetExitRoom();

                if (x > 10)
                {
                    return;
                }
            }

            SetRoomDoors();
            InstantiateMaze(mazeObject.transform);

            OnMazeGenerated?.Invoke(_takenPositions);
        }
        // Currently only uses the recursive backtracking algorithm
        public void BuildFromOrigin(int rowOrigin, int columnOrigin)
        {
            ResetMaze();
            BuildOrigin = m_Maze[rowOrigin, columnOrigin];

            // recursive backtracking
            var currentCell = BuildOrigin;

            currentCell.Status = AbstractMazeCellStatuses.Ready;
            while (currentCell != null)
            {
                // neighbor options
                var neighborOptions = new List <AbstractMazeCell <T> >();

                // push north neighbor
                if (currentCell.Row - 1 > -1)
                {
                    if (!m_Maze[currentCell.Row - 1, currentCell.Column].Status.Equals(AbstractMazeCellStatuses.Ready))
                    {
                        neighborOptions.Add(m_Maze[currentCell.Row - 1, currentCell.Column]);
                    }
                }
                // push west neighbor
                if (currentCell.Column - 1 > -1)
                {
                    if (!m_Maze[currentCell.Row, currentCell.Column - 1].Status.Equals(AbstractMazeCellStatuses.Ready))
                    {
                        neighborOptions.Add(m_Maze[currentCell.Row, currentCell.Column - 1]);
                    }
                }
                // push east neighbor
                if (currentCell.Column + 1 < Columns)
                {
                    if (!m_Maze[currentCell.Row, currentCell.Column + 1].Status.Equals(AbstractMazeCellStatuses.Ready))
                    {
                        neighborOptions.Add(m_Maze[currentCell.Row, currentCell.Column + 1]);
                    }
                }
                // push south neighbor
                if (currentCell.Row + 1 < Rows)
                {
                    if (!m_Maze[currentCell.Row + 1, currentCell.Column].Status.Equals(AbstractMazeCellStatuses.Ready))
                    {
                        neighborOptions.Add(m_Maze[currentCell.Row + 1, currentCell.Column]);
                    }
                }

                // if there are options, choose one and push currentCell to stack
                if (neighborOptions.Count > 0)
                {
                    DeadEnd = false;
                    // choose a neighbor at random
                    var index      = Random.Next(0, neighborOptions.Count);
                    var chosenCell = neighborOptions[index];

                    // push currentCell onto stack
                    BuildStack.Push(currentCell);

                    // whichever neighbor was chosen needs to have a path declared to and from currentCell
                    if (chosenCell.Row == currentCell.Row)
                    {
                        if (chosenCell.Column == currentCell.Column - 1) // west neighbor
                        {
                            currentCell.West_Neighbor = chosenCell;
                            chosenCell.East_Neighbor  = currentCell;
                        }
                        else // east neighbor => chosenCell.Column == currentCell.Column + 1
                        {
                            currentCell.East_Neighbor = chosenCell;
                            chosenCell.West_Neighbor  = currentCell;
                        }
                    }
                    else
                    {
                        if (chosenCell.Row == currentCell.Row - 1) // north neighbor
                        {
                            currentCell.North_Neighbor = chosenCell;
                            chosenCell.South_Neighbor  = currentCell;
                        }
                        else // south neighbor => chosenCell.Row == currentCell.Row + 1
                        {
                            currentCell.South_Neighbor = chosenCell;
                            chosenCell.North_Neighbor  = currentCell;
                        }
                    }

                    // make chosen into current after processing
                    chosenCell.Status = AbstractMazeCellStatuses.Ready;
                    currentCell       = chosenCell;
                }
                // there are no neighbor options, pop a cell off the stack and make it current
                else
                {
                    OnFinalProcessingCell?.Invoke(currentCell);
                    if (!DeadEnd)
                    {
                        DeadEnd = true;
                        OnDeadEndCreation?.Invoke(currentCell);
                    }
                    if (BuildStack.Count > 0)
                    {
                        currentCell = BuildStack.Pop();
                    }
                    else
                    {
                        currentCell = null;
                    }
                }
            }
            // the origin is always a dead end, too
            OnDeadEndCreation?.Invoke(BuildOrigin);

            // the maze is generated
            OnMazeGenerated?.Invoke(m_Maze);
        }