예제 #1
0
        internal override IEnumerable <MazeTransformationStep> InternalGenerateMazeFullSize()
        {
            InitializeMaze();
            entrance = new MazeCoordinate(upperleft.X + 1 + Random.Next(this.CurrentMaze.GetWidth() - 2), upperleft.Y);

            pointStack.Push(entrance);

            Nullable <MazeCoordinate> newCorridor;

            while (pointStack.Count() != 0)
            {
                newCorridor = FindWay();

                if (newCorridor == null)
                {
                    newCorridor = pointStack.Pop(); // One step back
                    if (newCorridor != null && CurrentMaze.WouldChangeMazeFieldType(newCorridor.Value, MazeFieldType.Corridor))
                    {
                        yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor));
                    }
                }
                else
                {
                    pointStack.Push(newCorridor.Value);
                    yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor));
                }
            }

            yield return(TryPlaceEntrance());

            yield return(TryPlaceExit());
        }
예제 #2
0
        internal override MazeTransformationStep TryPlaceExit()
        {
            List <MazeCoordinate> possibleExits = new List <MazeCoordinate>();

            // collect all possible exits
            for (int i = CurrentMaze.GetWidth() - 2; i >= 1; i--)
            {
                possibleExits.Add(new MazeCoordinate(i, downright.Y));
            }

            // check in random order if exit is valid
            while (possibleExits.Count > 0)
            {
                var possibleExit = possibleExits.ElementAt(Random.Next(possibleExits.Count));

                if (CurrentMaze.GetMazeTypeOnPos(possibleExit.X, possibleExit.Y + 1) == MazeFieldType.Corridor)
                {
                    return(CurrentMaze.SetMazeTypeOnPos(possibleExit, MazeFieldType.Exit));
                }
                else
                {
                    possibleExits.Remove(possibleExit);
                }
            }

            // TODO Maybe not the best way to handle this, but the maze is useless without valid exit.
            throw new Exception("Could not find a suitable exit position.");
        }
예제 #3
0
        private IEnumerable <MazeTransformationStep> RekursiveDiv(MazeCoordinate recUpperleft, MazeCoordinate recDownright, bool horizontal)
        {
            int width   = recDownright.X - recUpperleft.X;
            int height  = recUpperleft.Y - recDownright.Y;
            int minSize = 0;

            Strategy currentStrategy = CheckWhichStrategyToUse(width, height);

            if (!(width < minSize && height < minSize))
            {
                // Override the random decision for horizontal/vertical wall placement, this reduces long stretched corridors

                if (width > height)
                {
                    horizontal = false;
                }
                else
                {
                    horizontal = true;
                }

                if (horizontal)
                {// Horizontal
                    int newWallY = TryPlaceWallHorizontal(recUpperleft, recDownright, currentStrategy);
                    if (newWallY > 0)
                    {
                        for (int i = 1; i < width; i++)
                        { // Create wall
                            yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(recUpperleft.X + i, newWallY), MazeFieldType.Wall));
                        }

                        // Place corridor
                        int randX = FindHorizontalCorridor(ref recUpperleft, ref recDownright);
                        yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(randX, newWallY), MazeFieldType.Corridor));

                        // up
                        MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y);
                        MazeCoordinate downrightNew = new MazeCoordinate(recDownright.X, newWallY);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }

                        // down
                        upperleftNew = new MazeCoordinate(recUpperleft.X, newWallY);
                        downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }
                    }
                }
                else
                {// Vertical
                    int newWallX = TryPlaceWallVertical(recUpperleft, recDownright, currentStrategy);
                    if (newWallX > 0)
                    {
                        for (int i = 1; i < height; i++)
                        { // Create Wall
                            yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, recDownright.Y + i), MazeFieldType.Wall));
                        }

                        // Place corridor
                        int randY = FindVerticalCorridor(ref recUpperleft, ref recDownright);
                        yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, randY), MazeFieldType.Corridor));

                        //left
                        MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y);
                        MazeCoordinate downrightNew = new MazeCoordinate(newWallX, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }

                        //right
                        upperleftNew = new MazeCoordinate(newWallX, recUpperleft.Y);
                        downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }
                    }
                }
            }
        }