Ejemplo n.º 1
0
            public Node(WallInfo info)
            {
                this.wallInfo = info;

                this.valDis = 0;
                this.valSrc = 0;
                this.parent = null;
            }
Ejemplo n.º 2
0
 /// <summary>
 /// 获取指定迷宫墙信息
 /// </summary>
 /// <param name="x">横向坐标</param>
 /// <param name="y">纵向坐标</param>
 /// <returns>迷宫墙信息,不存在则返回null</returns>
 public WallInfo this[int x, int y]
 {
     get
     {
         return(GetWallInfo(x, y));
     }
     private set
     {
         WallInfo wInfo = GetWallInfo(x, y);
         if (wInfo != null)
         {
             wInfo = value;
         }
         else
         {
             throw new Exception("Maze>this[int x, int y]:GetWallInfo is null.");
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 查找路径
        /// </summary>
        /// <param name="maze"></param>
        /// <param name="wStart"></param>
        /// <param name="wStop"></param>
        /// <param name="bMode">是否访问斜对角节点</param>
        /// <returns></returns>
        public List <WallInfo> FindPath(Maze maze, WallInfo wStart, WallInfo wStop, bool bMode = false)
        {
            //初始化寻路节点列表
            InitList(maze);

            //起始节点
            Node startNode = _nodeList[maze.GetIndex(wStart)];
            Node endNode   = _nodeList[maze.GetIndex(wStop)];

            //未检查列表
            List <Node> openNode = new List <Node>();
            //已检查列表
            List <Node> closeNode = new List <Node>();

            //初始化检查列表
            openNode.Add(startNode);

            Node currentNode = null;
            Node tempNode    = null;

            while (openNode.Count > 0)
            {
                //设置当前结点
                currentNode = openNode[0];

                //取得最优节点
                foreach (var item in openNode)
                {
                    if (item.valSum < currentNode.valSum ||                                    //总权值最优
                        item.valSum == currentNode.valSum && item.valDis < currentNode.valDis) //或者相同情况下距目标最哦近
                    {
                        currentNode = item;
                    }
                }

                //将最优节点从未检测列表中删除,并添加到已检测列表中
                openNode.Remove(currentNode);
                closeNode.Add(currentNode);

                //如果当前结点为结束节点
                if (currentNode == endNode)
                {//生成并返回路径
                    return(GenericPath(startNode, endNode));
                }

                //访问周边节点
                for (int x = -1, y = -1; x <= 1; x++)
                {
                    for (y = -1; y <= 1; y++)
                    {
                        if (x == 0 && y == 0)
                        {//不访问自身节点
                            continue;
                        }

                        if (!bMode && Math.Abs(x + y) != 1)
                        {//不访问斜对角节点
                            continue;
                        }

                        //获取周边节点实例
                        tempNode = _nodeList[maze.GetIndex(currentNode.wallInfo.x + x, currentNode.wallInfo.y + y)];

                        if (tempNode.wallInfo.hasWall || closeNode.Contains(tempNode))
                        {//当节点为墙或已在已访问列表中时,跳出当前循环
                            continue;
                        }

                        //计算当前结点到startNode的权值
                        int nValSrc = currentNode.valSrc + GetNodeDistance(currentNode, tempNode);

                        bool hasNode = openNode.Contains(tempNode);               //是否存在于未检查列表中
                        if (!hasNode || nValSrc < tempNode.valSrc)
                        {                                                         //如果不在未检测列表中或距离起点更近
                            tempNode.valSrc = nValSrc;                            //更新权值
                            tempNode.valDis = GetNodeDistance(endNode, tempNode); //更新权值
                            tempNode.parent = currentNode;                        //设置父节点

                            if (!hasNode)
                            {//如果没有在检测列表中
                                openNode.Add(tempNode);
                            }
                        }
                    }
                }

                currentNode = null;
                tempNode    = null;
            }

            return(null);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 随机普里姆算法生成迷宫
        /// </summary>
        private void RandomPrim()
        {
            //墙数组下标极限
            int nWidthLimit  = _x - 2;
            int nHeightLimit = _y - 2;

            //起点
            int nTarX = 1;
            int nTarY = 1;

            //标记起点
            GetWallInfo(nTarX, nTarY).hasWall = false;

            List <BlockWallInfo> neighBlockWallInfo = new List <BlockWallInfo>();
            WallInfo             tempWall           = null;

            //记录邻墙,初始化需要拆的墙
            if (nTarY < nHeightLimit)
            {
                tempWall = GetWallInfo(nTarX, nTarY + 1);//Up
                if (tempWall != null)
                {
                    neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Up));//记录邻墙及其所在方向
                }
            }
            if (nTarY > 1)
            {
                tempWall = GetWallInfo(nTarX, nTarY - 1);//Down
                if (tempWall != null)
                {
                    neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Down));
                }
            }
            if (nTarX < nWidthLimit)
            {
                tempWall = GetWallInfo(nTarX + 1, nTarY);//Right
                if (tempWall != null)
                {
                    neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Right));
                }
            }
            if (nTarX > 1)
            {
                tempWall = GetWallInfo(nTarX - 1, nTarY);//Left
                if (tempWall != null)
                {
                    neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Left));
                }
            }

            int           nIndex        = 0;
            BlockWallInfo tempBlackWall = null;
            WallInfo      tempWall2     = null;

            while (neighBlockWallInfo.Count > 0)//是否还有未拆的墙
            {
                //随机选择一面墙
                nIndex = _rand.Next(neighBlockWallInfo.Count);

                //找出此墙对面的目标格
                tempBlackWall = neighBlockWallInfo[nIndex];
                switch (tempBlackWall.wallDirect)
                {
                case WallType.Up:
                    nTarX = tempBlackWall.info.x;
                    nTarY = tempBlackWall.info.y + 1;
                    break;

                case WallType.Down:
                    nTarX = tempBlackWall.info.x;
                    nTarY = tempBlackWall.info.y - 1;
                    break;

                case WallType.Left:
                    nTarX = tempBlackWall.info.x - 1;
                    nTarY = tempBlackWall.info.y;
                    break;

                case WallType.Right:
                    nTarX = tempBlackWall.info.x + 1;
                    nTarY = tempBlackWall.info.y;
                    break;
                }

                tempWall = GetWallInfo(nTarX, nTarY);//获取目标格
                if (tempWall != null && tempWall.hasWall)
                {
                    //连通目标格
                    tempWall.hasWall           = false;
                    tempBlackWall.info.hasWall = false;

                    //添加目标格的邻格
                    if (nTarY > 1)                                //Down
                    {
                        tempWall = GetWallInfo(nTarX, nTarY - 1); //获取目标格下面的邻墙
                        if (tempWall != null && tempWall.hasWall)
                        {
                            tempWall2 = GetWallInfo(nTarX, nTarY - 2);//获取目标格下面邻墙下面的目标格
                            if (tempWall2 != null && tempWall2.hasWall)
                            {
                                neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Down));//添加邻墙及其方向
                            }
                        }
                    }

                    if (nTarY < nHeightLimit)//Up
                    {
                        tempWall = GetWallInfo(nTarX, nTarY + 1);
                        if (tempWall != null && tempWall.hasWall)
                        {
                            tempWall2 = GetWallInfo(nTarX, nTarY + 2);
                            if (tempWall2 != null && tempWall.hasWall)
                            {
                                neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Up));
                            }
                        }
                    }

                    if (nTarX < nWidthLimit)//Right
                    {
                        tempWall = GetWallInfo(nTarX + 1, nTarY);
                        if (tempWall != null && tempWall.hasWall)
                        {
                            tempWall2 = GetWallInfo(nTarX + 2, nTarY);
                            if (tempWall2 != null && tempWall2.hasWall)
                            {
                                neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Right));
                            }
                        }
                    }

                    if (nTarX > 1)//Left
                    {
                        tempWall = GetWallInfo(nTarX - 1, nTarY);
                        if (tempWall != null && tempWall.hasWall)
                        {
                            tempWall2 = GetWallInfo(nTarX - 2, nTarY);
                            if (tempWall2 != null && tempWall2.hasWall)
                            {
                                neighBlockWallInfo.Add(new BlockWallInfo(tempWall, WallType.Left));
                            }
                        }
                    }
                }
                //移除此墙
                neighBlockWallInfo.RemoveAt(nIndex);

                tempWall      = null;
                tempWall2     = null;
                tempBlackWall = null;
            }
        }
Ejemplo n.º 5
0
 public BlockWallInfo(WallInfo info, WallType wallDirect)
 {
     this.info       = info;
     this.wallDirect = wallDirect;
 }
Ejemplo n.º 6
0
        public string SelectWall(WallInfo info)
        {
            if (info.isFindRoad)
            {//为查找的路径
                return("●");
            }

            string ch = string.Empty;

            switch (info.type)
            {
            case WallType.None:
                ch = "  ";
                break;

            case WallType.Up:
                ch = "│";
                break;

            case WallType.Down:
                ch = "│";
                break;

            case WallType.Left:
                ch = "─";
                break;

            case WallType.Right:
                ch = "─";
                break;

            case WallType.UpDown:
                ch = "│";
                break;

            case WallType.LeftRight:
                ch = "─";
                break;

            case WallType.LeftUp:
                ch = "┘";
                break;

            case WallType.LeftDown:
                ch = "┐";
                break;

            case WallType.RightUp:
                ch = "└";
                break;

            case WallType.RightDown:
                ch = "┌";
                break;

            case WallType.LeftUpRight:
                ch = "┴";
                break;

            case WallType.UpRightDown:
                ch = "├";
                break;

            case WallType.RigthDownLeft:
                ch = "┬";
                break;

            case WallType.DownLeftUp:
                ch = "┤";
                break;

            case WallType.LeftUpRightDown:
                ch = "┼";
                break;

            default:
                ch = string.Empty;
                break;
            }

            return(ch);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// 使用A*寻路查找路径
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <param name="bMode">是否走斜线</param>
 /// <returns></returns>
 public List <WallInfo> FindPath(WallInfo start, WallInfo end, bool bMode = false)
 {
     return(_findPath.FindPath(this, start, end, bMode));
 }
Ejemplo n.º 8
0
 /// <summary>
 /// 获取墙的序号
 /// </summary>
 /// <param name="info">墙信息</param>
 /// <returns></returns>
 public int GetIndex(WallInfo info)
 {
     return(info.x + info.y * _x);
 }