Esempio n. 1
0
        /// <summary>
        /// Just do some initialization and call the main routine,
        /// that is analyze_cell()
        /// </summary>
        public void GenerateMaze(int sizeX, int sizeY, int smoothness, int seed)
        {
            iSmooth    = smoothness;
            MazeSizeX  = sizeX;
            MazeSizeY  = sizeY;
            maze_base  = new int[MazeSizeX * MazeSizeY];
            maze_data  = new byte[MazeSizeX, MazeSizeY];
            stateStack = new FastStack <cMazeState>();
            r          = new Random(seed);
            MazeInit();
            cMazeState state = new cMazeState(r.Next() % MazeSizeX, r.Next() % MazeSizeY, 0);

            analyze_cell(state, r);
        }
Esempio n. 2
0
        /// <summary>
        /// Just do some initialization and call the main routine,
        /// that is analyze_cell()
        /// </summary>
        /// <param name="sizeX"></param>
        /// <param name="sizeY"></param>
        /// <param name="seed"></param>
        public void GenerateMaze(int sizeX, int sizeY, int seed, int smoothness)
        {
            iSmooth   = smoothness;
            MSIZEX    = sizeX;
            MSIZEY    = sizeY;
            maze_base = new int[MSIZEX * MSIZEY];
            maze_data = new Byte[MSIZEX, MSIZEY];

            s_stack = new Stack();
            r       = new Random(seed);

            MazeInit(r);

            cMazeState s = new cMazeState(r.Next() % MSIZEX, r.Next() % MSIZEY, 0);

            analyze_cell(s, r);
        }
Esempio n. 3
0
 public cMazeState( cMazeState s )
 {
     x=s.x; y=s.y; dir=s.dir;
 }
Esempio n. 4
0
        /// <summary>
        /// This is the main routine.
        /// The algorithm is pretty simple and very efficient.
        /// At the beginnins there are walls everywhere.
        /// 
        /// The algorithm walks around the maze choosing the
        /// random path at every step and looks if it can
        /// remove the wall between the cells.
        /// 
        /// The test that allows to remove the wall is also really
        /// simple: if the two cells are already connected then
        /// the wall is not allowed.
        /// 
        /// The only trick is the check whether the two cells are
        /// connected. To answer this question, the algorithm
        /// keeps the chains of connected walls. It works like this:
        /// - each chain consist of pointers to consecutive cells
        ///   in the chain, last pointer is -1 and the cell with 
        ///   such value in maze_base is called base_cell of a cell. 
        /// - at the beginning there are no chains, looking
        ///   at maze_base[cellindex] you can find the value of -1
        /// - when two chains are merged, the pointer of the base cell
        ///   of one of chains is changed so that it points to the 
        ///   base_cell of the other chain.
        ///   
        /// I've read about a similar trick by Tarjan but it looked
        /// much complicated ( or maybe I didn't understand it well ).
        /// Nevertheless, my code works really fast! Try to beat it.  
        /// </summary>
        /// <param name="s"></param>
        /// <param name="r"></param>
        void analyze_cell( cMazeState s, Random r )
        {
            bool bEnd = false, found;
            int indexSrc, indexDest, tDir=0, prevDir=0;

            while (true)
            {
                if ( s.dir == 15 )
                {
                    while ( s.dir == 15 )
                    {
                        s = (cMazeState)s_stack.pop();
                        if ( s == null )
                        {
                            bEnd = true;
                            break;
                        }
                    }
                    if ( bEnd == true ) break;
                }
                else
                {
                    do
                    {
                        prevDir = tDir;
                        tDir = (int)Math.Pow( 2, r.Next()%4 );

                        if ( (r.Next()%32) < iSmooth )
                            if ( (s.dir & prevDir) == 0 )
                                tDir = prevDir;

                        if ( (s.dir & tDir) != 0 )
                            found = true;
                        else
                            found = false;
                    } while ( found == true && s.dir!=15 );

                    s.dir |= tDir;

                    indexSrc  = cell_index( s.x, s.y );

                    // direction W
                    if ( tDir == 1 && s.x > 0 )
                    {
                        indexDest = cell_index( s.x-1, s.y );
                        if ( base_cell( indexSrc ) != base_cell ( indexDest ) )
                        {
                            merge( indexSrc, indexDest );
                            maze_data[s.x, s.y] |= (byte)Direction.W;

                            s_stack.push ( new cMazeState(s) );
                            s.x -= 1;s.dir = 0;
                        }
                    }

                    // direction E
                    if ( tDir == 2 && s.x < MSIZEX-1 )
                    {
                        indexDest = cell_index( s.x+1, s.y );
                        if ( base_cell( indexSrc ) != base_cell ( indexDest ) )
                        {
                            merge( indexSrc, indexDest );
                            maze_data[s.x+1, s.y] |= (byte)Direction.W;

                            s_stack.push ( new cMazeState(s) );
                            s.x += 1;s.dir = 0;
                        }
                    }

                    // direction N
                    if ( tDir == 4 && s.y > 0 )
                    {
                        indexDest = cell_index( s.x, s.y-1 );
                        if ( base_cell( indexSrc ) != base_cell ( indexDest ) )
                        {
                            merge( indexSrc, indexDest );
                            maze_data[s.x, s.y] |= (byte)Direction.N;

                            s_stack.push ( new cMazeState(s) );
                            s.y -= 1;s.dir = 0;
                        }
                    }

                    // direction S
                    if ( tDir == 8 && s.y < MSIZEY-1 )
                    {
                        indexDest = cell_index( s.x, s.y+1 );
                        if ( base_cell( indexSrc ) != base_cell ( indexDest ) )
                        {
                            merge( indexSrc, indexDest );
                            maze_data[s.x, s.y+1] |= (byte)Direction.N;

                            s_stack.push ( new cMazeState(s) );
                            s.y += 1;s.dir = 0;
                        }
                    }
                } // else
            } // while
        }
Esempio n. 5
0
        /// <summary>
        /// Just do some initialization and call the main routine,
        /// that is analyze_cell()
        /// </summary>
        /// <param name="sizeX"></param>
        /// <param name="sizeY"></param>
        /// <param name="seed"></param>
        public void GenerateMaze( int sizeX, int sizeY, int seed, int smoothness )
        {
            iSmooth = smoothness;
            MSIZEX  = sizeX;
            MSIZEY  = sizeY;
            maze_base = new int[MSIZEX*MSIZEY];
            maze_data = new Byte[MSIZEX, MSIZEY];

            s_stack = new Stack();
            r = new Random ( seed );

            MazeInit( r );

            cMazeState s = new cMazeState(r.Next()%MSIZEX, r.Next()%MSIZEY, 0);
            analyze_cell( s, r );
        }
Esempio n. 6
0
        /// <summary>
        /// This is the main routine.
        /// The algorithm is pretty simple and very efficient.
        /// At the beginnins there are walls everywhere.
        ///
        /// The algorithm walks around the maze choosing the
        /// random path at every step and looks if it can
        /// remove the wall between the cells.
        ///
        /// The test that allows to remove the wall is also really
        /// simple: if the two cells are already connected then
        /// the wall is not allowed.
        ///
        /// The only trick is the check whether the two cells are
        /// connected. To answer this question, the algorithm
        /// keeps the chains of connected walls. It works like this:
        /// - each chain consist of pointers to consecutive cells
        ///   in the chain, last pointer is -1 and the cell with
        ///   such value in maze_base is called base_cell of a cell.
        /// - at the beginning there are no chains, looking
        ///   at maze_base[cellindex] you can find the value of -1
        /// - when two chains are merged, the pointer of the base cell
        ///   of one of chains is changed so that it points to the
        ///   base_cell of the other chain.
        ///
        /// I've read about a similar trick by Tarjan but it looked
        /// much complicated ( or maybe I didn't understand it well ).
        /// Nevertheless, my code works really fast! Try to beat it.
        /// </summary>
        /// <param name="s"></param>
        /// <param name="r"></param>
        void analyze_cell(cMazeState s, Random r)
        {
            bool bEnd = false, found;
            int  indexSrc, indexDest, tDir = 0, prevDir = 0;

            while (true)
            {
                if (s.dir == 15)
                {
                    while (s.dir == 15)
                    {
                        s = (cMazeState)s_stack.pop();
                        if (s == null)
                        {
                            bEnd = true;
                            break;
                        }
                    }
                    if (bEnd == true)
                    {
                        break;
                    }
                }
                else
                {
                    do
                    {
                        prevDir = tDir;
                        tDir    = (int)Math.Pow(2, r.Next() % 4);

                        if ((r.Next() % 32) < iSmooth)
                        {
                            if ((s.dir & prevDir) == 0)
                            {
                                tDir = prevDir;
                            }
                        }

                        if ((s.dir & tDir) != 0)
                        {
                            found = true;
                        }
                        else
                        {
                            found = false;
                        }
                    } while (found == true && s.dir != 15);

                    s.dir |= tDir;

                    indexSrc = cell_index(s.x, s.y);

                    // direction W
                    if (tDir == 1 && s.x > 0)
                    {
                        indexDest = cell_index(s.x - 1, s.y);
                        if (base_cell(indexSrc) != base_cell(indexDest))
                        {
                            merge(indexSrc, indexDest);
                            maze_data[s.x, s.y] |= (byte)Direction.W;

                            s_stack.push(new cMazeState(s));
                            s.x -= 1; s.dir = 0;
                        }
                    }

                    // direction E
                    if (tDir == 2 && s.x < MSIZEX - 1)
                    {
                        indexDest = cell_index(s.x + 1, s.y);
                        if (base_cell(indexSrc) != base_cell(indexDest))
                        {
                            merge(indexSrc, indexDest);
                            maze_data[s.x + 1, s.y] |= (byte)Direction.W;

                            s_stack.push(new cMazeState(s));
                            s.x += 1; s.dir = 0;
                        }
                    }

                    // direction N
                    if (tDir == 4 && s.y > 0)
                    {
                        indexDest = cell_index(s.x, s.y - 1);
                        if (base_cell(indexSrc) != base_cell(indexDest))
                        {
                            merge(indexSrc, indexDest);
                            maze_data[s.x, s.y] |= (byte)Direction.N;

                            s_stack.push(new cMazeState(s));
                            s.y -= 1; s.dir = 0;
                        }
                    }

                    // direction S
                    if (tDir == 8 && s.y < MSIZEY - 1)
                    {
                        indexDest = cell_index(s.x, s.y + 1);
                        if (base_cell(indexSrc) != base_cell(indexDest))
                        {
                            merge(indexSrc, indexDest);
                            maze_data[s.x, s.y + 1] |= (byte)Direction.N;

                            s_stack.push(new cMazeState(s));
                            s.y += 1; s.dir = 0;
                        }
                    }
                } // else
            }     // while
        }         // function
Esempio n. 7
0
 public cMazeState(cMazeState s)
 {
     x = s.x; y = s.y; dir = s.dir;
 }