public Node(WallInfo info) { this.wallInfo = info; this.valDis = 0; this.valSrc = 0; this.parent = null; }
/// <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."); } } }
/// <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); }
/// <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; } }
public BlockWallInfo(WallInfo info, WallType wallDirect) { this.info = info; this.wallDirect = wallDirect; }
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); }
/// <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)); }
/// <summary> /// 获取墙的序号 /// </summary> /// <param name="info">墙信息</param> /// <returns></returns> public int GetIndex(WallInfo info) { return(info.x + info.y * _x); }