Exemplo n.º 1
0
        /// <summary>
        /// The GenerateNewMaze method is called to generate a new maze.
        /// </summary>
        /// <returns></returns>
        public async Task GenerateNewMaze()
        {
            try
            {
                if (CanGenerateMaze)
                {
                    MazeState = MazeState.MazeGenerating;

                    // Clear the maze and stack.
                    ResetMaze();
                    _mazeGeneratorStack = new Stack <MazeCell>();

                    // Select a random cell to start.
                    MazeCell startCell = ChooseRandomCell();
                    startCell.CellState = CellState.Visited;

                    // Generate the new maze.
                    await GenerateNewMaze(startCell);

                    // Set the start/end cells.
                    if (MazeCells.Count > 0)
                    {
                        MazeCells.First().CellType = CellType.Start;
                        MazeCells.Last().CellType  = CellType.End;
                    }

                    MazeState = MazeState.MazeGenerated;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Maze.GenerateNewMaze(): " + ex.ToString());
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// The GenerateNewMaze method is called to generate a new maze.
        /// The Randomized Prim's algorithm is used to generate the maze.
        /// https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Prim's_algorithm
        /// </summary>
        /// <returns></returns>
        public async Task GenerateNewMaze()
        {
            try
            {
                if (CanGenerateMaze)
                {
                    ResetMaze();                                           // Clear the maze.

                    SimulationState = SimulationState.MazeGenerating;      // Update the simulation state.

                    List <MazeCell> frontierCells = new List <MazeCell>(); // Create a collection of maze walls.

                    // Select a random cell to start.
                    MazeCell initialCell = ChooseRandomCell();
                    initialCell.CellType = CellType.Passage;
                    frontierCells.AddRange(RetrieveFrontierNeighbours(initialCell));  // Add the neighbouring cells to the frontier.

                    while (frontierCells.Count > 0)
                    {
                        // Choose a random cell from the frontier.
                        MazeCell currentCell = frontierCells.ElementAt(_randomNumberGenerator.Next(frontierCells.Count));
                        frontierCells.Remove(currentCell);  // Remove this cell from the frontier.

                        if (currentCell.CellType == CellType.Passage)
                        {
                            // If the cell is already a passage, move on to the next frontier cell.
                            continue;
                        }

                        // Retrieve the "passage" neighbours for the current cell (these neighbours are already part of the maze).
                        List <MazeCell> passageNeighbours = RetrievePassageNeighbours(currentCell);
                        if (passageNeighbours.Count > 0)
                        {
                            // Select a random "passage" neighbour.
                            MazeCell selectedNeighbour = passageNeighbours.ElementAt(_randomNumberGenerator.Next(passageNeighbours.Count));

                            // Connect the current cell to the selected neighbour.
                            ConnectCells(currentCell, selectedNeighbour);
                            currentCell.CellType = CellType.Passage;

                            // Retrieve the frontier neighbours for the current cell, and add them to the frontier.
                            frontierCells.AddRange(RetrieveFrontierNeighbours(currentCell));
                        }

                        await Task.Delay(Constants.MazeGenerationDelayMilliSeconds);
                    }

                    // Set the start/end cells.
                    MazeCell startCell = MazeCells.First(x => x.CellType == CellType.Passage);
                    startCell.CellRole = CellRole.Start;
                    MazeCell endCell = MazeCells.Last(x => x.CellType == CellType.Passage);
                    endCell.CellRole = CellRole.End;

                    // Place the robot at the start cell.
                    _robot.SetLocation(startCell);

                    SimulationState = SimulationState.MazeGenerated;    // Update the simulation state.
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Maze.GenerateNewMaze(): " + ex.ToString());
            }
        }