public void StartSearchPath()
        {
            if (start == null)
                throw new InvalidNodeException(InvalidNodeTypes.NoStart);//起点为空  引发异常
            if (end == null)
                throw new InvalidNodeException(InvalidNodeTypes.NoEnd);//终点为空 引发异常
            path = null;
            openList.Clear();
            closeList.Clear();//清理开启节点和关闭节点
            currentNode = start;// 现节点为开始节点
            SearchPath(currentNode);
        }
        //寻路递归,受保护的虚方法,允许在子类重写寻路算法
        protected virtual void SearchPath(StarNode starNode)
        {
            
            openList.Remove(starNode);//从开启列表中移除
            closeList.Add(starNode);//从关闭列表中加入
            AddNodeToOpenList();//把当前点周围可通过的点加入到开放列表中
            if (closeList.Contains(end))//如果终点在关闭列表中,找到路径
            {
                
                StarNode node = starNode.Parent;//将starNode的父节点赋值给node1
                path = new StarNodeCollection();//声明一个路径节点集合
                do
                {
                    path.Add(node);//将node结点放入路径
                    node = node.Parent;
                } while (node != null && !node.Equals(start));//路径中循环添加父节点(逆向返回添加)
                path.Reverse();//将路径反转 
                return;
            }
            else if (openList.Count == 0)//终点不在关闭列表,开放列表已空,没有可通行的路径
            {
                
                return;
            }
            currentNode = GetNextNode();
            
            SearchPath(currentNode);//迭代过程
        }
        public StarNode GetNextNode()//获得当前节点的下一个最佳节点
        {
            openList.SortByF();
            return openList[0];//返回开启列表中F值最小的节点
        }        private void AddNodeToOpenList()//把当前点周围可通过的点加入到开放列表中
        {            //上
            if (currentNode.Y - 1 >= 0 && map[currentNode.X, currentNode.Y - 1] == 0 && !closeList.Contains(currentNode.X, currentNode.Y - 1))
            {  //不是第一行  上节点map值为0  上节点不在关闭列表中
                CheckNodeStatus(currentNode.X, currentNode.Y - 1);
            }
            //下
            if (currentNode.Y + 1 < map.Height && map[currentNode.X, currentNode.Y + 1] == 0 && !closeList.Contains(currentNode.X, currentNode.Y + 1))
            {//不是最底部一行  下节点map值为0 下节点不再关闭列表中
                CheckNodeStatus(currentNode.X, currentNode.Y + 1);
            }
            //左
            if (currentNode.X - 1 >= 0 && map[currentNode.X - 1, currentNode.Y] == 0 && !closeList.Contains(currentNode.X - 1, currentNode.Y))
            {
                CheckNodeStatus(currentNode.X - 1, currentNode.Y);
            }
            //右
            if (currentNode.X + 1 < map.Width && map[currentNode.X + 1, currentNode.Y] == 0 && !closeList.Contains(currentNode.X + 1, currentNode.Y))
            {
                CheckNodeStatus(currentNode.X + 1, currentNode.Y);
            }
            if (allDirection)
            {
                //允许8方向寻路,查找对角线上的节点
                //上左
                if (currentNode.X - 1 >= 0 && currentNode.Y - 1 >= 0 && map[currentNode.X - 1, currentNode.Y - 1] == 0 && !closeList.Contains(currentNode.X - 1, currentNode.Y - 1))
                { //不在最左上  左上节点map值为0 左上节点不在关闭列表中
                    CheckNodeStatus(currentNode.X - 1, currentNode.Y - 1);
                }
                //上右
                if (currentNode.X + 1 < map.Width && currentNode.Y - 1 >= 0 && map[currentNode.X + 1, currentNode.Y - 1] == 0 && !closeList.Contains(currentNode.X + 1, currentNode.Y + 1))
                {
                    CheckNodeStatus(currentNode.X + 1, currentNode.Y - 1);
                }
                //下左
                if (currentNode.X - 1 >= 0 && currentNode.Y + 1 < map.Height && map[currentNode.X - 1, currentNode.Y + 1] == 0 && !closeList.Contains(currentNode.X - 1, currentNode.Y + 1))
                {
                    CheckNodeStatus(currentNode.X - 1, currentNode.Y + 1);
                }
                //下右
                if (currentNode.X + 1 < map.Width && currentNode.Y + 1 < map.Height && map[currentNode.X + 1, currentNode.Y + 1] == 0 && !closeList.Contains(currentNode.X + 1, currentNode.Y + 1))
                {
                    CheckNodeStatus(currentNode.X + 1, currentNode.Y + 1);
                }
            }
        }        private void CheckNodeStatus(int x, int y)//x,y为courrent附近的节点
        {
            StarNode childNode = new StarNode(x, y);//将坐标封装到节点
            childNode.G = CalcG(childNode);         
            childNode.H = CalcH(childNode,end);    //计算该点的H值和G值
            if (openList.Contains(childNode))
            {
                //如果节点已经在开放列表中
                StarNode node = openList[openList.FindIndex(childNode)];//openList[openList.FindIndex(childNode)]与childNode只有X Y相同  其余的不一定相同 故不可以用childNode代替openList[openList.FindIndex(childNode)]
                if (currentNode.G + childNode.G <= node.G)
                {
                     //如果从当前节点的父节点到该节点的G值小于等于该节点原有的G值
                    node.Parent = currentNode;//将该节点的父节点设为当前节点,并重新计算G值
                    node.G = currentNode.G + childNode.G;
                }
            }
            else
            { //如果节点不在开放列表中 
                childNode.Parent = currentNode;  //当前结点为下一结点的父结点
                childNode.G += currentNode.G;   //计算下一结点的G值
                openList.Add(childNode);         //将下一结点加入到开放列表中
            }
        }        //计算两个节点间的H值
        private int CalcH(StarNode node1, StarNode node2)   // H = 从网格上那个方格移动到终点B的预估移动耗费
        {
            int h = Math.Abs(node2.X - node1.X) + Math.Abs(node2.Y - node1.Y);//从网格上那个方格移动到终点B的网格数       
            return h * 10;
        }        //计算指定节点相对当前节点的G值
        private int CalcG(StarNode node)                   //G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费
        {
            if (node.X == currentNode.X || node.Y == currentNode.Y)//上下左右返回10
                return 10;
            else                                          //斜对角返回14
                return 14;
        }这是曼哈顿A*算法   看代码好像要是进入死胡同的话是出不来的   可是程序运行却能绕过死胡同  这是怎么回事   请高手指点一二