示例#1
0
    public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime)
    {
        // Initialization
        List <GraphVertex> elementsToProcess = new List <GraphVertex>();

        IEnumerator <GraphVertex> enumerator = maze.GetEnumerator();

        enumerator.MoveNext();
        GraphVertex first = enumerator.Current;

        first.SetVisited();
        foreach (GraphVertex gv in first.GetMarkedNeighbours(MarkType.Unvisited))
        {
            elementsToProcess.Add(gv);
        }


        // Process
        GraphVertex gvToProcess;
        GraphVertex gvToLinkTo;

        while (elementsToProcess.Count != 0)
        {
            // Get the cells to link
            gvToProcess = elementsToProcess [Random.Range(0, elementsToProcess.Count)];
            gvToLinkTo  = gvToProcess.GetRandomMarkedNeighbour(MarkType.Visited);

            // Link the cells
            gvToProcess.RemoveBorderBetweenCells(gvToLinkTo);

            // Setup the next iteration
            gvToProcess.SetVisited();
            elementsToProcess.Remove(gvToProcess);
            foreach (GraphVertex gv in gvToProcess.GetMarkedNeighbours(MarkType.Unvisited))
            {
                // We add each unmarked adjacent cell as long as it is not already in the list
                if (!elementsToProcess.Contains(gv))
                {
                    elementsToProcess.Add(gv);
                }
            }


            // Visualization
            Manager.ClearMazeObjects();
            MazeViewer.DisplayGrid(maze, vertexPrefab);
            yield return(new WaitForSecondsRealtime(deltaTime));
        }
        Manager.ClearMazeObjects();
        MazeViewer.DisplayGrid(maze, vertexPrefab);
    }
示例#2
0
    // Generates the maze according to the current attributes
    public void GenerateMaze()
    {
        // Delete the previous maze (if any)
        Manager.ClearMazeObjects();

        // Construction of the initial maze, with walls everywhere
        IEnumerable <GraphVertex> maze = UndirectedGraph.GridCellUndirectedGraph(1, this.nbLines, this.nbColumns, this.nbBorders, this.allowTeleporters);

        // Selection of the right generator
        MazeGenerator generator = null;

        switch (this.genType)
        {
        case GeneratorType.DFS:
        {
            generator = new DFSGenerator();
            break;
        }

        case GeneratorType.Prim:
        {
            generator = new PrimGenerator();
            break;
        }

        case GeneratorType.Wilson:
        {
            generator = new WilsonGenerator();
            break;
        }
        }

        // Generation of the maze
        if (this.animated)
        {
            currentCoroutine = generator.AnimatedGeneration(maze, vertexPrefab, 0);
            StartCoroutine(currentCoroutine);
        }
        else
        {
            generator.Generate(maze);
            MazeViewer.DisplayGrid(maze, vertexPrefab);
        }

        // Center the camera on the maze
        SetupCamera(maze);

        // Add a character to the maze
        GameObject.Instantiate(character);
    }
示例#3
0
    public void init()
    {
        // Ensure MazeViewer object is initialized;
        // Populate notMaze with vectors of all cells.
        viewer = gameObject.GetComponent <MazeViewer>();
        if (!viewer.initFlag)
        {
            viewer.init();
        }

        maze         = new HashSet <WilsonCell>();
        mazeCoords   = new HashSet <Vector2Int>();
        notMaze      = new HashSet <Vector2Int>();
        trail        = new HashSet <Vector2Int>();
        orderedTrail = new List <Vector2Int>();
        moves        = new List <Vector2Int>();
        Random.InitState(seed);

        mazeCount   = maze.Count;
        iterations  = 0;
        maxCells    = sizeX * sizeY;
        targetCells = (int)(maxCells * cellDensity);

        for (int x = 0; x < sizeX; x++)
        {
            for (int y = 0; y < sizeY; y++)
            {
                notMaze.Add(new Vector2Int(x, y));
            }
        }
        //Initialize maze.
        if (mazeCount < 1)
        {
            Vector2Int initial =
                new Vector2Int(Random.Range(0, sizeX - 1), Random.Range(0, sizeY - 1));
            maze.Add(new WilsonCell(initial));
            mazeCoords.Add(initial);
            notMaze.Remove(initial);
        }
        viewer.RefreshEmpty();
        viewer.RefreshMaze();
        initFlag = true;
    }
示例#4
0
    public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime)
    {
        // Initialization
        Stack <GraphVertex> stack = new Stack <GraphVertex>();

        IEnumerator <GraphVertex> enumerator = maze.GetEnumerator();

        enumerator.MoveNext();
        GraphVertex current = enumerator.Current;

        stack.Push(current);

        // Algorithm
        GraphVertex next;

        while (!(stack.Count == 0))
        {
            current = stack.Peek();
            current.SetVisited();
            next = current.GetRandomMarkedNeighbour(MarkType.Unvisited);

            if (next == null)               // dead end, every neighbour of the current cell has been visited
            {
                stack.Pop();
            }
            else
            {
                current.RemoveBorderBetweenCells(next);
                stack.Push(next);
            }


            // Visualization
            Manager.ClearMazeObjects();
            MazeViewer.DisplayGrid(maze, vertexPrefab);
            yield return(new WaitForSecondsRealtime(deltaTime));
        }
    }
    public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime)
    {
        // Initialization
        Stack <GraphVertex> currentPath = new Stack <GraphVertex>();

        IEnumerator <GraphVertex> enumerator = maze.GetEnumerator();

        enumerator.MoveNext();
        GraphVertex first = enumerator.Current;

        first.SetVisited();

        List <GraphVertex> processedGV = new List <GraphVertex> ();

        processedGV.Add(first);


        // Process
        GraphVertex previous = first;
        GraphVertex next     = first.GetRandomMarkedNeighbour(MarkType.Unvisited);

        next.Mark = MarkType.TemporaryVisited;
        currentPath.Push(next);
        while (currentPath.Count != 0)
        {
            List <GraphVertex> list = currentPath.Peek().Neighbours;
            list.Remove(previous);              // we don't want to go back on our step (yet)
            previous = next;

            // Update of the next cell to check
            int randomIndex = Random.Range(0, list.Count);
            next = list [randomIndex];


            if (next.Mark == MarkType.Visited)
            {
                // We have reached the maze so we backtrack the path to process it
                while (currentPath.Count > 1)
                {
                    GraphVertex gv = currentPath.Pop();
                    gv.RemoveBorderBetweenCells(currentPath.Peek());
                    gv.SetVisited();
                    processedGV.Add(gv);
                }
                GraphVertex lastGv = currentPath.Pop();
                lastGv.RemoveBorderBetweenCells(first);
                lastGv.SetVisited();
                processedGV.Add(lastGv);

                // Setup for the next path, we choose a new starting point
                foreach (GraphVertex gv in processedGV)
                {
                    GraphVertex tempSecond = gv.GetRandomMarkedNeighbour(MarkType.Unvisited);
                    if (tempSecond != null)
                    {
                        first     = gv;
                        previous  = first;
                        next      = tempSecond;
                        next.Mark = MarkType.TemporaryVisited;
                        currentPath.Push(next);
                        break;
                    }
                }

                // Visualization
                Manager.ClearMazeObjects();
                MazeViewer.DisplayGrid(maze, vertexPrefab);
                yield return(new WaitForSecondsRealtime(deltaTime));
            }
            else if (currentPath.Contains(next))
            {
                // There is a loop in the path so we restart the path
                while (currentPath.Count != 0)
                {
                    currentPath.Pop().Mark = MarkType.Unvisited;
                }
                // Setup for the rebooted path
                previous  = first;
                next      = first.GetRandomMarkedNeighbour(MarkType.Unvisited);
                next.Mark = MarkType.TemporaryVisited;
                currentPath.Push(next);
            }
            else
            {
                // We add "next" to the current path
                next.Mark = MarkType.TemporaryVisited;
                currentPath.Push(next);
            }
        }
        MazeViewer.DisplayGrid(maze, vertexPrefab);
    }
示例#6
0
 private void Awake()
 {
     viewer = GetComponent <MazeViewer>();
 }