Ejemplo n.º 1
0
    public List <GroundNode> FindPath(GroundNode _start, GroundNode _dest)   //경로가 없으면 null반환
    {
        List <GroundNode> openList  = new List <GroundNode>();
        List <GroundNode> closeList = new List <GroundNode>();
        List <GroundNode> path      = new List <GroundNode>();
        GroundNode        current   = null;

        //시작노드 정보 초기화
        _start.SetParent(_start);
        _start.CalcGScore();
        _start.CalcDist(_dest);

        //openList 초기화
        openList.Add(_start);

        while (openList.Count > 0)
        {                                           //openList가 전부 비워질 때까지
            current = LowestFScoreInList(openList); //openList에서 가장 적은 F비용 노드 선택

            if (current == _dest)
            {   //선택된 노드가 목적지인 경우
                CreatePath(_start, _dest, path);
                return(path);
            }

            openList.Remove(current);                             //선택한 노드를 openList에서 제거
            closeList.Add(current);                               //closeList에 추가

            List <GroundNode> neighbors = FindNeighbors(current); //인접노드 탐색

            for (int i = 0; i < neighbors.Count; i++)
            {
                if (closeList.IndexOf(neighbors[i]) >= 0)
                {
                    continue;
                }   //인접노드가 closeList에 있다면 무시
                if (openList.IndexOf(neighbors[i]) < 0)
                {   //openList에 없다면 추가하고 부모를 선택 노드로 설정
                    openList.Add(neighbors[i]);
                    neighbors[i].SetParent(current);
                    //G스코어와 목적지까지의 거리를 계산하여 노드내에 정보 저장
                    neighbors[i].SetGScore(neighbors[i].CalcGScore());
                    neighbors[i].SetHScore(neighbors[i].CalcDist(_dest));
                }

                //시작노드에서 Neighbor까지의 gScore가 current를 거쳐서 Neighbor까지 가는 gScore비용보다 싸면 무시
                if (current.GetGScore() + current.CalcDistNeighbor(neighbors[i]) >= neighbors[i].GetGScore())
                {
                    continue;
                }

                //current를 거쳐서 가는 것이 더 좋다면 Neighbor의 부모를 current로 변경하고 비용을 다시 계산함
                neighbors[i].SetParent(current);
                neighbors[i].SetGScore(current.GetGScore() + current.CalcDistNeighbor(neighbors[i]));
            }
        }   //while문 종료

        //openList가 전부 비었으므로 경로가 존재하지 않음
        return(null);
    }