protected override void Generate()
        {
            IMazeCell random_start = GetRandomCell();
            int       visited      = 1;

            while (visited < cells.Count)
            {
                EMazeDirection valid        = random_start.GenRandomNeighbourDirection();
                IMazeCell      pending_next = random_start.GetNeighbour(valid);

                if (pending_next != null)
                {
                    //言外之意,没被访问过
                    //means, not visited.
                    if (pending_next.ConnectionCount == 0)
                    {
                        random_start.ConnectionTo(valid);
                        random_start = pending_next;
                        visited++;
                    }
                    else
                    {
                        random_start = pending_next;
                        continue;
                    }
                }
            }
        }
        /// <summary>
        /// 注意:该算法对不规则图形非常不友好,如果一定要应用到不规则图形
        /// 需要做很多修改,因此建议直接禁止本算法应用到不规则图形上去。
        /// </summary>
        protected override void Generate()
        {
            List <IMazeCell>      temp_cell_collection = new List <IMazeCell>();
            List <EMazeDirection> filter_dir           = new List <EMazeDirection>();

            filter_dir.Add(EMazeDirection.North);
            filter_dir.Add(EMazeDirection.East);

            for (int iy = 0; iy < size_y; iy++)
            {
                for (int ix = 0; ix < size_x; ix++)
                {
                    IMazeCell cell = GetAt(ix, iy);
                    //尽管如此,还是可以利用fiter做一波优化,去掉重复代码!
                    EMazeDirection move_dir = cell.GenRandomNeighbourDirection(ESelectCondition.None, filter_dir);
                    if (move_dir == EMazeDirection.North)
                    {
                        temp_cell_collection.Add(cell);
                        IMazeCell dig_cell = temp_cell_collection[Random.Range(0, temp_cell_collection.Count)];
                        dig_cell.ConnectionTo(EMazeDirection.North);
                        temp_cell_collection.Clear();
                    }
                    else if (move_dir == EMazeDirection.East)
                    {
                        temp_cell_collection.Add(cell);
                        cell.ConnectionTo(EMazeDirection.East);
                    }
                }
            }
        }
예제 #3
0
        void Hunt(int visited)
        {
            IMazeCell hunt_result = null;

            for (int iy = size_y - 1; iy >= 0; iy--)
            //for (int iy = 0; iy < size_y;iy++ )
            {
                for (int ix = 0; ix < size_x; ix++)
                //for (int ix = size_x-1; ix >=0; ix--)
                {
                    hunt_result = GetAt(ix, iy);

                    //hunt result 必须是一个未访问过的点,并且他要链接一个已经访问过的点(隐含一定不会连接)
                    if (hunt_result.ConnectionCount == 0)
                    {
                        EMazeDirection dir = hunt_result.GenRandomNeighbourDirection(ESelectCondition.Visited);

                        if (dir != EMazeDirection.Invalid)
                        {
                            hunt_result.ConnectionTo(dir);
                            visited++;
                            Kill(visited, hunt_result);
                            break;
                        }
                    }
                }
            }
        }
예제 #4
0
        void Kill(int visited, IMazeCell start_point)
        {
            if (visited <= cells.Count)
            {
                do
                {
                    EMazeDirection move_dir = start_point.GenRandomNeighbourDirection(ESelectCondition.NoVisited);

                    if (move_dir == EMazeDirection.Invalid)
                    {
                        break;
                    }
                    IMazeCell next = start_point.GetNeighbour(move_dir);

                    start_point.ConnectionTo(move_dir);
                    start_point = next;
                    visited++;
                }while(true);

                //finish kill begin hunt.
                if (visited < cells.Count)
                {
                    Hunt(visited);
                }
            }
        }
        protected override void Generate()
        {
            Stack <IMazeCell> back_tracker = new Stack <IMazeCell>();

            //把起点塞进去
            back_tracker.Push(cells[0]);

            //如果栈空了,表示迷宫完成了。
            while (back_tracker.Count > 0)
            {
                //寻找栈顶元素
                IMazeCell start_node = back_tracker.Peek();

                //直接选择出,没访问过,且不连通的点。注意,不连通,但是有可能是已经访问过的,没访问过,一定不连通!
                EMazeDirection move_dir = start_node.GenRandomNeighbourDirection(ESelectCondition.NoVisited);

                //如果这个点的周围都已经访问过来,开始回溯,每次遍历回溯一格。直到找到下一个,周围有没访问过的点的节点。
                if (move_dir == EMazeDirection.Invalid)
                {
                    back_tracker.Pop();
                    continue;
                }

                //点周围有没访问过,也没联通的点
                start_node.ConnectionTo(move_dir);
                back_tracker.Push(start_node.GetNeighbour(move_dir));
            }
        }
        public override void PostProcess(MazeAlgorithm maze_algorithm)
        {
            int size_x = maze_algorithm.size_x;
            int size_y = maze_algorithm.size_y;

            for (int iy = 0; iy < size_y; iy++)
            {
                for (int ix = 0; ix < size_x; ix++)
                {
                    IMazeCell cell = maze_algorithm.GetAt(ix, iy);

                    //Dead Ends
                    if (cell != null && cell.ConnectionCount == 1 && Random.Range(0.0f, 1.0f) < braidingrate)
                    {
                        bool processed = false;
                        for (int i = 0; i < (int)EMazeDirection.DirectionCount; i++)
                        {
                            EMazeDirection dir = (EMazeDirection)i;

                            //尚未联通的点
                            if (cell.IsConnectedTo(dir) == true)
                            {
                                //只做反向联通,确保不会出现孤点
                                EMazeDirection inverse_dir = MazeAlgorithm.InvertDirection(dir);
                                IMazeCell      invert_cell = cell.GetNeighbour(inverse_dir);
                                if (invert_cell != null)
                                {
                                    cell.ConnectionTo(inverse_dir);
                                    processed = true;
                                }
                            } //END OF IF Connected to
                        }     //END OF FOR Neighbours

                        if (processed == false)
                        {
                            EMazeDirection connect_dir = cell.GenRandomNeighbourDirection(ESelectCondition.NoConnected);

                            if (connect_dir != EMazeDirection.DirectionCount)
                            {
                                cell.ConnectionTo(connect_dir);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 这个算法同样不能胜任,不规则格子的迷宫。
        /// 因为他会产生孤立点。
        /// </summary>
        protected override void Generate()
        {
            List <EMazeDirection> dir_filter = new List <EMazeDirection>();

            dir_filter.Add(EMazeDirection.North);
            dir_filter.Add(EMazeDirection.East);

            for (int iy = 0; iy < size_y; iy++)
            {
                for (int ix = 0; ix < size_x; ix++)
                {
                    IMazeCell cell = GetAt(ix, iy);

                    //算法优化,不能每次都判断是不是在墙角,那种判断对于不规则迷宫是无效的,且麻烦的。
                    //如果只希望沿着某两个方向扩展,更科学的方式是使用DirectionFilter 这样可以方便的产生更多的选择组合。
                    EMazeDirection move_to_dir = cell.GenRandomNeighbourDirection(ESelectCondition.None, dir_filter);

                    if (move_to_dir != EMazeDirection.DirectionCount)
                    {
                        cell.ConnectionTo(move_to_dir);
                    }
                }
            }
        }
        protected override void Generate()
        {
            IMazeCell        random_start = GetRandomCell();
            List <IMazeCell> unvisited    = new List <IMazeCell>(cells);

            unvisited.Remove(random_start);

            //前半段,用AldourBroder
            while (unvisited.Count > cells.Count / 2)
            {
                EMazeDirection valid        = random_start.GenRandomNeighbourDirection();
                IMazeCell      pending_next = random_start.GetNeighbour(valid);

                if (pending_next != null)
                {
                    //言外之意,没被访问过
                    //means, not visited.
                    if (pending_next.ConnectionCount == 0)
                    {
                        random_start.ConnectionTo(valid);
                        random_start = pending_next;
                        unvisited.Remove(random_start);
                    }
                    else
                    {
                        random_start = pending_next;
                        continue;
                    }
                }
            }

            //后半段,用Wilson
            List <IMazeCell> temp_path = new List <IMazeCell>();

            random_start = unvisited[Random.Range(0, unvisited.Count)];

            while (unvisited.Count > 0)
            {
                temp_path.Clear();
                temp_path.Add(random_start);

                while (true)
                {
                    //如果有强烈需求,可以考虑增加接口,暂时先这样做。
                    EMazeDirection dir  = temp_path[temp_path.Count - 1].GenRandomNeighbourDirection();
                    IMazeCell      next = temp_path[temp_path.Count - 1].GetNeighbour(dir);

                    //没有形成环路
                    if (unvisited.Contains(next) == false)
                    {
                        //开始联通了
                        temp_path.Add(next);

                        for (int i = 0; i < temp_path.Count - 1; i++)
                        {
                            unvisited.Remove(temp_path[i]);
                            temp_path[i].ConnectionTo(temp_path[i].LastRandomNeibourDirection);
                        }

                        if (unvisited.Count > 0)
                        {
                            random_start = unvisited[Random.Range(0, unvisited.Count)];
                        }
                        break;
                    }
                    //形成了环路
                    else if (temp_path.Contains(next) == true)
                    {
                        break;
                    }

                    temp_path.Add(next);
                }
            }
        }