Ejemplo n.º 1
0
    void OpenNode(AStarWithOutClosedListNode currentNode, Vector2 direction)                 //有缺陷,假设一个格子已经开了但有更低价的格子可以指向,缺少对这时候的处理
    {
        AStarWithOutClosedListNode newNode = GetNode(currentNode, direction);

        if (newNode == null || !newNode.canThrough)
        {
            return;                                                             //如果没获取到新节点或新节点不能通行则直接return
        }
        switch (newNode.state)
        {
        case AStarWithOutClosedListNodeState.unopened:
            DoOpenNode(currentNode, newNode);
            break;

        case AStarWithOutClosedListNodeState.opened:
            if (currentNode.startToCost < newNode.nextNode.startToCost)         //如果新节点已经开了但从起点到指向的节点的成本比当前节点高
            {
                ReopenNode(currentNode, newNode);
            }
            break;

        case AStarWithOutClosedListNodeState.closed:
            break;
        }
    }
Ejemplo n.º 2
0
    string GetDirectionText(AStarWithOutClosedListNode node)
    {
        if (node == null || node.nextNode == null)
        {
            return("");
        }

        Vector2 direction = node.nextNode.position - node.position;

        if (direction == Vector2.up)
        {
            return("↑");
        }
        if (direction == Vector2.right)
        {
            return("→");
        }
        if (direction == Vector2.down)
        {
            return("↓");
        }
        if (direction == Vector2.left)
        {
            return("←");
        }

        return("");
    }
Ejemplo n.º 3
0
    public void FindPath(Vector2 startPosition, Vector2 endPosition)
    {
        if (!InMatrix(startPosition) || !InMatrix(endPosition) || !GetNode(startPosition).canThrough || !GetNode(endPosition).canThrough)
        {
            return;
        }

        ResetMatrix(_matrix.GetLength(0), _matrix.GetLength(1));

        _openedList = new List <AStarWithOutClosedListNode>();

        _startPosition = new Vector2((int)startPosition.x, (int)startPosition.y);       //这步极其重要,一定要把起点终点的坐标进行精确,否则算成本的时候会出现不可预料的小数进而造成误差
        _endPosition   = new Vector2((int)endPosition.x, (int)endPosition.y);

        _openedList.Add(GetNode(_startPosition));               //将起点加入开表

        while (_openedList.Count > 0)
        {
            AStarWithOutClosedListNode currentNode = GetMinimumCostNodeInOpenedList();

            if (IsDestination(currentNode))
            {
                break;
            }

            OpenNode(currentNode, Vector2.up);
            OpenNode(currentNode, Vector2.right);
            OpenNode(currentNode, Vector2.down);
            OpenNode(currentNode, Vector2.left);

            CloseNode(currentNode);
        }
    }
Ejemplo n.º 4
0
 public void Reset()     //寻路开始时清空成本和指向
 {
     _state       = AStarWithOutClosedListNodeState.unopened;
     _nextNode    = null;
     _startToCost = 0;
     _toEndCost   = 0;
     _totalCost   = 0;
 }
Ejemplo n.º 5
0
    public void Pathfind_CantFind()
    {
        AStarWithOutClosedList aStar = new AStarWithOutClosedList(7, 7);

        Vector2 startPosition = new Vector2(0, 0);
        Vector2 endPosition   = new Vector2(6, 6);

        aStar.SetObstacle(new Vector2(0, 1));
        aStar.SetObstacle(new Vector2(1, 1));
        aStar.SetObstacle(new Vector2(2, 1));
        aStar.SetObstacle(new Vector2(4, 1));
        aStar.SetObstacle(new Vector2(4, 2));
        aStar.SetObstacle(new Vector2(4, 3));
        aStar.SetObstacle(new Vector2(5, 3));
        aStar.SetObstacle(new Vector2(6, 3));
        aStar.SetObstacle(new Vector2(1, 4));
        aStar.SetObstacle(new Vector2(2, 4));
        aStar.SetObstacle(new Vector2(3, 4));
        aStar.SetObstacle(new Vector2(2, 5));
        aStar.SetObstacle(new Vector2(0, 6));
        aStar.SetObstacle(new Vector2(1, 6));

        aStar.FindPath(startPosition, endPosition);

        /*
         *  N   N   0   0   0   0   E
         *
         *  ↓   ←   N   0   0   0   0
         *
         *  ↓   N   N   N   0   0   0
         *
         *  →   →   →   ↓   N   N   N
         *
         *  →   →   →   ↓   N   ↓   ←
         *
         *  N   N   N   ↓   N   ↓   ←
         *
         *  S   ←   ←   ←   ←   ←   ←
         */
        AStarWithOutClosedListNode[,] matrix    = aStar.matrix;
        AStarWithOutClosedListNode[,] nextNodes = new AStarWithOutClosedListNode[7, 7]
        {
            { null, matrix[0, 0], matrix[1, 0], matrix[2, 0], matrix[3, 0], matrix[4, 0], matrix[5, 0] },
            { null, null, null, matrix[3, 0], null, matrix[5, 0], matrix[5, 1] },
            { matrix[1, 2], matrix[2, 2], matrix[3, 2], matrix[3, 1], null, matrix[5, 1], matrix[5, 2] },
            { matrix[1, 3], matrix[2, 3], matrix[3, 3], matrix[3, 2], null, null, null },
            { matrix[0, 3], null, null, null, null, null, null },
            { matrix[0, 4], matrix[0, 5], null, null, null, null, null },
            { null, null, null, null, null, null, null }
        };
        for (int x = 0; x < 7; x++)
        {
            for (int y = 0; y < 7; y++)
            {
                Assert.AreEqual(nextNodes[y, x], aStar.matrix[x, y].nextNode);      //横y竖x,何等反人类,而且竟然严格符合了数组下标顺序:前面是第一层,后面是第二层
            }
        }
    }
Ejemplo n.º 6
0
    Color GetNodeColor(AStarWithOutClosedListNode node, float maxStartToCost, float maxToEndCost)
    {
        if (!node.canThrough)
        {
            return(Color.black);
        }

        Color nodeRed  = Color.red * node.startToCost / maxStartToCost;
        Color nodeBlue = Color.blue * node.toEndCost / maxToEndCost;

        return(nodeRed + nodeBlue + Color.gray * 0.5f);
    }
Ejemplo n.º 7
0
    void DisplayPath()
    {
        AStarWithOutClosedListNode currentNode = _aStar.GetNode(_endPosition);

        if (currentNode == null || currentNode.nextNode == null)
        {
            return;
        }

        while (currentNode.nextNode != null)
        {
            AddGreen(currentNode);

            currentNode = currentNode.nextNode;
        }

        AddGreen(currentNode);
    }
Ejemplo n.º 8
0
    AStarWithOutClosedListNode GetMinimumCostNodeInOpenedList()
    {
        AStarWithOutClosedListNode minimumCostNode = _openedList[0];

        foreach (AStarWithOutClosedListNode currentNode in _openedList)
        {
            if (currentNode.totalCost < minimumCostNode.totalCost)
            {
                minimumCostNode = currentNode;
            }
            else if (currentNode.totalCost == minimumCostNode.totalCost && currentNode.toEndCost < minimumCostNode.toEndCost)   //当前节点总成本和最小成本节点总成本相同,但距离终点更近的话
            {
                minimumCostNode = currentNode;
            }
        }


        return(minimumCostNode);
    }
Ejemplo n.º 9
0
    public void Pathfind_CanFind_NoObstacle()
    {
        AStarWithOutClosedList aStar = new AStarWithOutClosedList(7, 7);

        Vector2 startPosition = new Vector2(0, 0);
        Vector2 endPosition   = new Vector2(6, 6);

        aStar.FindPath(startPosition, endPosition);

        /*
         *  ↓   ←   ←   ←   ←   ←   E
         *
         *  ↓   ←   ↑   ↑   ↑   ↑   0
         *
         *  ↓   ←   0   0   0   0   0
         *
         *  ↓   ←   0   0   0   0   0
         *
         *  ↓   ←   0   0   0   0   0
         *
         *  ↓   ←   0   0   0   0   0
         *
         *  S   ←   0   0   0   0   0
         */
        AStarWithOutClosedListNode[,] matrix    = aStar.matrix;
        AStarWithOutClosedListNode[,] nextNodes = new AStarWithOutClosedListNode[7, 7]
        {
            { null, matrix[0, 0], null, null, null, null, null },
            { matrix[0, 0], matrix[0, 1], null, null, null, null, null },
            { matrix[0, 1], matrix[0, 2], null, null, null, null, null },
            { matrix[0, 2], matrix[0, 3], null, null, null, null, null },
            { matrix[0, 3], matrix[0, 4], null, null, null, null, null },
            { matrix[0, 4], matrix[0, 5], matrix[2, 6], matrix[3, 6], matrix[4, 6], matrix[5, 6], null },
            { matrix[0, 5], matrix[0, 6], matrix[1, 6], matrix[2, 6], matrix[3, 6], matrix[4, 6], matrix[5, 6] }
        };
        for (int x = 0; x < 7; x++)
        {
            for (int y = 0; y < 7; y++)
            {
                Assert.AreEqual(nextNodes[y, x], aStar.matrix[x, y].nextNode);      //二维数组赋值是按照横竖x的方式进行的,也就是说上面的矩阵写错了,要转置,这就是一个用 [y, x] 一个用 [x, y] 的原因
            }
        }
    }
Ejemplo n.º 10
0
    public AStarWithOutClosedList(int width, int height)
    {
        if (width < 0)
        {
            width = 0;                              //防止传入负数
        }
        if (height < 0)
        {
            height = 0;                             //防止传入负数
        }
        _matrix = new AStarWithOutClosedListNode[width, height];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                _matrix[x, y] = new AStarWithOutClosedListNode(x, y);
            }
        }
    }
Ejemplo n.º 11
0
    void MouseMiddleDown()
    {
        Vector2 position = GetMousePosition();

        AStarWithOutClosedListNode node = _aStar.GetNode(position);

        if (node == null)
        {
            return;
        }

        if (node.canThrough)
        {
            _aStar.SetObstacle(position);
        }
        else
        {
            _aStar.RemoveObstacle(position);
        }

        DoFindPath();
    }
Ejemplo n.º 12
0
 void ReopenNode(AStarWithOutClosedListNode currentNode, AStarWithOutClosedListNode openNode)
 {
     openNode.Open(currentNode, _endPosition);
 }
Ejemplo n.º 13
0
 bool IsDestination(AStarWithOutClosedListNode currentNode)
 {
     return(currentNode == GetNode(_endPosition));
 }
Ejemplo n.º 14
0
    void AddGreen(AStarWithOutClosedListNode currentNode)
    {
        Vector2 position = currentNode.position;

        _displayMatrix[(int)position.x, (int)position.y].GetComponentInChildren <Image>().color += Color.green;
    }
Ejemplo n.º 15
0
    void DoOpenNode(AStarWithOutClosedListNode currentNode, AStarWithOutClosedListNode openNode)
    {
        openNode.Open(currentNode, _endPosition);

        _openedList.Add(openNode);
    }
Ejemplo n.º 16
0
 void CloseNode(AStarWithOutClosedListNode node)
 {
     _openedList.Remove(node);
     node.Close();
 }
Ejemplo n.º 17
0
 void DisplayANode(AStarWithOutClosedListNode node, GameObject displayer, float maxStartToCost, float maxToEndCost)
 {
     displayer.GetComponentInChildren <Image>().color = GetNodeColor(node, maxStartToCost, maxToEndCost);
     displayer.GetComponentInChildren <Text>().text   = GetDirectionText(node);
 }
Ejemplo n.º 18
0
 public void Open(AStarWithOutClosedListNode nextNode, Vector2 destination)
 {
     _state    = AStarWithOutClosedListNodeState.opened;
     _nextNode = nextNode;
     ComputeCost(destination);
 }
Ejemplo n.º 19
0
 public AStarWithOutClosedListNode GetNode(AStarWithOutClosedListNode node, Vector2 direction)
 {
     return(GetNode(node.position + direction));
 }