コード例 #1
0
 public override bool[] PreferredDirections(MazeSquare sq)
 {
     if (outline[sq.XPos, sq.YPos] == true)
     {
         return(inside.PreferredDirections(sq));
     }
     else
     {
         return(outside.PreferredDirections(sq));
     }
 }
コード例 #2
0
            /// <summary>
            /// Returns the preferred directions, as determined by one of the fields.
            /// </summary>
            /// <param name="sq"></param>
            /// <returns></returns>
            public override bool[] PreferredDirections(MazeSquare sq)
            {
                // Size of one field.
                int m = ((this.maze.XSize - 1) / this.fields.GetLength(0)) + 1;
                int n = ((this.maze.YSize - 1) / this.fields.GetLength(1)) + 1;

                // Index of this field.
                int i = sq.XPos / m;
                int j = sq.YPos / n;

                IrregularMazeShape shape = this.fields[i, j];

                return(shape.PreferredDirections(sq));
            }
コード例 #3
0
        /// <summary>
        /// Convert all undecided walls to either closed or open.
        /// In the resulting maze, there must be a path from every square to every other square.
        /// There must not be any circles, i.e. the maze must have a tree-like structure.
        /// </summary>
        private void BuildMaze()
        {
            // We hold a number of active squares in a stack.
            // Make the initial capacity sufficient to hold all squares.
            //
            Stack <MazeSquare> stack = new Stack <MazeSquare>(xSize * ySize);

            List <MazeSquare>   outlineSquares = new List <MazeSquare>();
            List <WallPosition> outlineWalls   = new List <WallPosition>();

            #region Start with a single random cell in the stack.

            while (true)
            {
                int        x  = random.Next(xSize);
                int        y  = random.Next(ySize);
                MazeSquare sq = this[x, y];
                if (sq.MazeId == this.MazeId)
                {
                    sq.isConnected = true;
                    stack.Push(sq);
                    break;
                }
            }

            #endregion

            #region Extend the maze by visiting the cells next to those in the stack.

            while (stack.Count > 0)
            {
                List <WallPosition> unresolvedWalls = new List <WallPosition>((int)WallPosition.WP_NUM);
                MazeSquare          sq0             = stack.Pop();

                // Collect the unfixed walls of sq0.
                //
                for (WallPosition wp = WallPosition.WP_MIN; wp <= WallPosition.WP_MAX; wp++)
                {
                    switch (sq0[wp])
                    {
                    case WallState.WS_MAYBE:
                        MazeSquare sq = sq0.NeighborSquare(wp);

                        if (sq.isConnected || sq.MazeId != sq0.MazeId)
                        {
                            sq0[wp] = sq[MazeSquare.OppositeWall(wp)] = WallState.WS_CLOSED;
                        }
                        else
                        {
                            unresolvedWalls.Add(wp);
                        }
                        break;     // WS_MAYBE

                    case WallState.WS_OUTLINE:
                        outlineSquares.Add(sq0);
                        outlineWalls.Add(wp);
                        break;     // WS_OUTLINE
                    }
                } // foreach wp

                // Discard this square if it has no unresolved walls.
                if (unresolvedWalls.Count == 0)
                {
                    // Note: This is the only place that may end the loop.
                    // If the stack is empty: Open one outline wall.
                    if (stack.Count == 0)
                    {
                        while (outlineSquares.Count > 0)
                        {
                            // Select a random square with an outline wall.
                            int          p  = random.Next(outlineSquares.Count);
                            MazeSquare   sq = outlineSquares[p];
                            WallPosition wp = outlineWalls[p];
                            outlineSquares.RemoveAt(p);
                            outlineWalls.RemoveAt(p);

                            if (sq[wp] == WallState.WS_OUTLINE)
                            {
                                sq[wp] = WallState.WS_MAYBE;
                                stack.Push(sq);
                                // This square will be used in the next iteration.
                                break; // from while(outlineSquares)
                            }
                        }
                    }

                    continue; // no walls to choose from
                }

                // Add the current cell to the stack.
                // Note: Do this before replacing unresolvedWalls with preferredWalls.
                if (unresolvedWalls.Count > 1)
                {
                    stack.Push(sq0);
                }

                // Use only preferred wall positions.
                if (unresolvedWalls.Count > 1 && irregularMazeShape != null &&
                    (random.Next(100) < irregularMazeShape.ApplicationPercentage(this.irregularity)))
                {
                    bool[] preferredPositions          = irregularMazeShape.PreferredDirections(sq0);
                    List <WallPosition> preferredWalls = new List <WallPosition>(unresolvedWalls.Count);
                    foreach (WallPosition p in unresolvedWalls)
                    {
                        if (preferredPositions[(int)p])
                        {
                            preferredWalls.Add(p);
                        }
                    }
                    if (preferredWalls.Count > 0)
                    {
                        unresolvedWalls = preferredWalls;
                    }
                }

                // Choose one wall.
                WallPosition wp0 = unresolvedWalls[random.Next(unresolvedWalls.Count)];
                MazeSquare   sq1 = sq0.NeighborSquare(wp0);

                // Open the wall.
                sq0[wp0] = sq1[MazeSquare.OppositeWall(wp0)] = WallState.WS_OPEN;

                // Add the new cell to the stack.
                sq1.isConnected = true;
                stack.Push(sq1);
            } // while stack is not empty

            #endregion
        }