Example #1
0
        private bool check(myTree tree, myNode node)
        {
            bool c = true;

            foreach (myNode n in tree.nodes)
            {
                if (n.X == node.X && n.Y == node.Y)
                {
                    c = false;
                }
            }
            return(c);
        }
Example #2
0
    // Start is called before the first frame update
    void Start()
    {
        /*
         * List<Transform> enemyList = new List<Transform>();
         * for (int i = 0; i < 10; i++) {
         *  GameObject empty = new GameObject();
         *  Transform newTransform = empty.transform;
         *  newTransform.position = new Vector3(i, 0, 0);
         *  enemyList.Add(newTransform);
         * }
         * KdTree<Transform> enemyKdTree = new KdTree<Transform>();
         * enemyKdTree.AddAll(enemyList);
         * Transform now = enemyKdTree.FindClosest(new Vector3(5.2f, 0, 0));
         * print(now.position);*/
        //以上方法, 是參考 http://gyanendushekhar.com/2020/02/23/find-closest-enemy-in-unity-3d/ 使用 https://github.com/orifmilod/KdTree-Unity3D : Used in this example 的結構

        List <myNode> nodeList = new List <myNode>();

        //之後就 for(i彩帶
        //         for(j點
        for (int i = 0; i < 10; i++)
        {
            GameObject one = new GameObject();              //要洗成 GameObject 的 component
            one.AddComponent <myNode>();                    //加進去
            myNode node = one.GetComponent <myNode>();      //再拿出來
            //node.I = i; node.J = j;
            node.transform.position = new Vector3(i, 0, 0); //將來就有 tranform 可以做 KdTree的比較了...
            nodeList.Add(node);                             //這個 node有 tranform哦!!!!
        }
        KdTree <myNode> nodeKdTree = new KdTree <myNode>();

        nodeKdTree.AddAll(nodeList);
        myNode nearest = nodeKdTree.FindClosest(new Vector3(4.2f, 0, 0));

        print("hahaha" + nearest.transform.position);
    }
Example #3
0
        private void label38_Click(object sender, EventArgs e)//ids
        {
            myNode gool   = new myNode(0, 0);
            bool   isGool = pictureBox1.Location.X == pictureBox2.Location.X ? true : false;
            myNode root   = new myNode(pictureBox1.Location.X, pictureBox1.Location.Y);

            root.level = 0;
            myTree IDS = new myTree(root);

            IDS.CurrentNode = root;
            int z = 367; bool b = true; int i = 0;

            for (int iz = 0; iz < z; iz++)
            {
                IDS.CurrentNode.Visited = true;
                List <myNode> newNodes = new List <myNode>();
                pictureBox3.Location = new Point(IDS.CurrentNode.X, IDS.CurrentNode.Y);

                if (pictureBox3.Bounds.IntersectsWith(pictureBox2.Bounds))
                {
                    gool = IDS.CurrentNode;
                    break;
                }


                myNode node1 = new myNode(IDS.CurrentNode.X + 10, IDS.CurrentNode.Y);
                pictureBox3.Location = new Point(node1.X, node1.Y);

                if (collision1())
                {
                    node1 = null;
                }
                else
                {
                    node1.Parent = IDS.CurrentNode;
                    node1.level  = IDS.CurrentNode.level + 1;

                    if (check(IDS, node1))
                    {
                        IDS.nodes.Add(node1);
                    }
                }
                newNodes.Add(node1);
                myNode node2 = new myNode(IDS.CurrentNode.X - 10, IDS.CurrentNode.Y);
                pictureBox3.Location = new Point(node2.X, node2.Y);

                if (collision1())
                {
                    node2 = null;
                }
                else
                {
                    node2.Parent = IDS.CurrentNode;
                    node2.level  = IDS.CurrentNode.level + 1;

                    if (check(IDS, node2))
                    {
                        IDS.nodes.Add(node2);
                    }
                }
                newNodes.Add(node2);
                myNode node3 = new myNode(IDS.CurrentNode.X, IDS.CurrentNode.Y + 10);
                pictureBox3.Location = new Point(node3.X, node3.Y);

                if (collision1())
                {
                    node3 = null;
                }
                else
                {
                    node3.Parent = IDS.CurrentNode;
                    node3.level  = IDS.CurrentNode.level + 1;

                    if (check(IDS, node3))
                    {
                        IDS.nodes.Add(node3);
                    }
                }
                newNodes.Add(node3);
                myNode node4 = new myNode(IDS.CurrentNode.X, IDS.CurrentNode.Y - 10);
                pictureBox3.Location = new Point(node4.X, node4.Y);

                if (collision1())
                {
                    node4 = null;
                }
                else
                {
                    node4.Parent = IDS.CurrentNode;
                    node4.level  = IDS.CurrentNode.level + 1;

                    if (check(IDS, node4))
                    {
                        IDS.nodes.Add(node4);
                    }
                }
                newNodes.Add(node4);
                IDS.CurrentNode = IDS.CurrentNode.expand(newNodes);
                IDS.CurrentNode = IDS.nodes[iz + 1];
                if (i == z - 1 && i < IDS.nodes.Count)
                {
                    ++z; iz = 0;
                }
                i++;
            }

            Stack path = new Stack();

            while (b)
            {
                path.Push(gool);
                gool = gool.Parent;
                if (gool == root)
                {
                    b = false;
                }
                break;
            }
            int time = 0;

            for (int iz = 0; iz < IDS.nodes.Count; iz++)
            {
                if (IDS.nodes[iz].Visited == true)
                {
                    time++;
                }
            }
            int PathCost = path.Count;

            while (path.Count != 0)
            {
                myNode temp = (myNode)path.Pop();
                pictureBox1.Location = new Point(temp.X, temp.Y);
                pictureBox1.Refresh();
                System.Threading.Thread.Sleep(50);
            }
            if (b == true)
            {
                MessageBox.Show("Congratolation \n your path cost = " + (Math.Abs((PathCost + IDS.nodes.Count) * (z - IDS.nodes.Count))) + " \n your space = " + IDS.nodes.Count + "\n your time = " + time);
            }
        }
Example #4
0
        private void label36_Click(object sender, EventArgs e)//dls
        {
            myNode gool   = new myNode(0, 0);
            bool   isGool = pictureBox1.Location.X == pictureBox2.Location.X ? true : false;
            myNode root   = new myNode(pictureBox1.Location.X, pictureBox1.Location.Y);

            root.level = 0;
            myTree DlS = new myTree(root);

            DlS.CurrentNode = root;

            for (int i = 0; i < 50; i++)
            {
                DlS.CurrentNode.Visited = true;
                List <myNode> newNodes = new List <myNode>();
                pictureBox3.Location = new Point(DlS.CurrentNode.X, DlS.CurrentNode.Y);

                if (pictureBox3.Bounds.IntersectsWith(pictureBox2.Bounds))
                {
                    gool = DlS.CurrentNode;
                    break;
                }


                myNode node1 = new myNode(DlS.CurrentNode.X + 10, DlS.CurrentNode.Y);
                pictureBox3.Location = new Point(node1.X, node1.Y);

                if (collision1())
                {
                    node1 = null;
                }
                else
                {
                    node1.Parent = DlS.CurrentNode;
                    node1.level  = DlS.CurrentNode.level + 1;

                    if (check(DlS, node1))
                    {
                        DlS.nodes.Add(node1);
                    }
                }
                newNodes.Add(node1);
                myNode node2 = new myNode(DlS.CurrentNode.X - 10, DlS.CurrentNode.Y);
                pictureBox3.Location = new Point(node2.X, node2.Y);

                if (collision1())
                {
                    node2 = null;
                }
                else
                {
                    node2.Parent = DlS.CurrentNode;
                    node2.level  = DlS.CurrentNode.level + 1;

                    if (check(DlS, node2))
                    {
                        DlS.nodes.Add(node2);
                    }
                }
                newNodes.Add(node2);
                myNode node3 = new myNode(DlS.CurrentNode.X, DlS.CurrentNode.Y + 10);
                pictureBox3.Location = new Point(node3.X, node3.Y);

                if (collision1())
                {
                    node3 = null;
                }
                else
                {
                    node3.Parent = DlS.CurrentNode;
                    node3.level  = DlS.CurrentNode.level + 1;

                    if (check(DlS, node3))
                    {
                        DlS.nodes.Add(node3);
                    }
                }
                newNodes.Add(node3);
                myNode node4 = new myNode(DlS.CurrentNode.X, DlS.CurrentNode.Y - 10);
                pictureBox3.Location = new Point(node4.X, node4.Y);

                if (collision1())
                {
                    node4 = null;
                }
                else
                {
                    node4.Parent = DlS.CurrentNode;
                    node4.level  = DlS.CurrentNode.level + 1;

                    if (check(DlS, node4))
                    {
                        DlS.nodes.Add(node4);
                    }
                }
                newNodes.Add(node4);
                DlS.CurrentNode.expand(newNodes);
                DlS.CurrentNode = DlS.nodes[i + 1];
            }

            Stack path = new Stack();
            bool  b    = true;

            while (b)
            {
                if (gool == root)
                {
                    b = false;
                }
                MessageBox.Show("sorry can't reach the goal☺");
                break;
            }
            int time = 0;

            for (int i = 0; i < DlS.nodes.Count; i++)
            {
                if (DlS.nodes[i].Visited == true)
                {
                    time++;
                }
            }
            int PathCost = path.Count;

            while (path.Count != 0)
            {
                myNode temp = (myNode)path.Pop();
                pictureBox1.Location = new Point(temp.X, temp.Y);
                pictureBox1.Refresh();
                System.Threading.Thread.Sleep(50);
            }
            if (b == true)
            {
                MessageBox.Show("Congratolation \n your path cost = " + PathCost + " \n your space = " + DlS.nodes.Count + "\n your time = " + time);
            }
        }
Example #5
0
        private void label33_Click(object sender, EventArgs e)//bfs
        {
            myNode gool   = new myNode(0, 0);
            bool   isGool = pictureBox1.Location.X == pictureBox2.Location.X ? true : false;
            myNode root   = new myNode(pictureBox1.Location.X, pictureBox1.Location.Y);

            root.level = 0;
            myTree BFS = new myTree(root);

            BFS.CurrentNode = root;
            //while (!isGool)
            //{
            for (int i = 0; i < BFS.nodes.Count; i++)
            {
                BFS.CurrentNode.Visited = true;
                List <myNode> newNodes = new List <myNode>();
                pictureBox3.Location = new Point(BFS.CurrentNode.X, BFS.CurrentNode.Y);

                if (pictureBox3.Bounds.IntersectsWith(pictureBox2.Bounds))
                {
                    gool = BFS.CurrentNode;
                    break;
                }

                // EXBAND NEW NODES
                myNode node1 = new myNode(BFS.CurrentNode.X + 10, BFS.CurrentNode.Y);
                pictureBox3.Location = new Point(node1.X, node1.Y);
                // System.Threading.Thread.Sleep(600);
                if (collision1())
                {
                    node1 = null;
                }
                else
                {
                    node1.Parent = BFS.CurrentNode;
                    node1.level  = BFS.CurrentNode.level + 1;
                    //if(!BFS.nodes.Contains(node1))
                    if (check(BFS, node1))
                    {
                        BFS.nodes.Add(node1);
                    }
                }
                newNodes.Add(node1);
                myNode node2 = new myNode(BFS.CurrentNode.X, BFS.CurrentNode.Y + 10);
                pictureBox3.Location = new Point(node2.X, node2.Y);
                // System.Threading.Thread.Sleep(600);
                if (collision1())
                {
                    node2 = null;
                }
                else
                {
                    node2.Parent = BFS.CurrentNode;

                    node2.level = BFS.CurrentNode.level;
                    //if (!BFS.nodes.Contains(node2))
                    if (check(BFS, node2))
                    {
                        BFS.nodes.Add(node2);
                    }
                }
                newNodes.Add(node2);
                myNode node3 = new myNode(BFS.CurrentNode.X - 10, BFS.CurrentNode.Y);
                pictureBox3.Location = new Point(node3.X, node3.Y);
                // System.Threading.Thread.Sleep(600);
                if (collision1())
                {
                    node3 = null;
                }
                else
                {
                    node3.Parent = BFS.CurrentNode;
                    node3.level  = BFS.CurrentNode.level + 1;
                    //if (!BFS.nodes.Contains(node3))
                    if (check(BFS, node3))
                    {
                        BFS.nodes.Add(node3);
                    }
                }
                newNodes.Add(node3);
                myNode node4 = new myNode(BFS.CurrentNode.X, BFS.CurrentNode.Y - 10);
                pictureBox3.Location = new Point(node4.X, node4.Y);
                // System.Threading.Thread.Sleep(600);
                if (collision1())
                {
                    node4 = null;
                }
                else
                {
                    node4.Parent = BFS.CurrentNode;
                    node4.level  = BFS.CurrentNode.level + 1;

                    //if (!BFS.nodes.Contains(node4))
                    if (check(BFS, node4))
                    {
                        BFS.nodes.Add(node4);
                    }
                }
                newNodes.Add(node4);
                BFS.CurrentNode.expand(newNodes);
                // MessageBox.Show(BFS.CurrentNode.X.ToString());

                BFS.CurrentNode = BFS.nodes[i + 1];
            }
            Stack path = new Stack();
            bool  b    = true;

            while (b)
            {
                path.Push(gool);
                gool = gool.Parent;
                if (gool == root)
                {
                    b = false;
                }
            }
            int time = 0;

            for (int i = 0; i < BFS.nodes.Count; i++)
            {
                if (BFS.nodes[i].Visited == true)
                {
                    time++;
                }
            }
            int PathCost = path.Count;

            while (path.Count != 0)
            {
                myNode temp = (myNode)path.Pop();
                pictureBox1.Location = new Point(temp.X, temp.Y);
                pictureBox1.Refresh();
                System.Threading.Thread.Sleep(50);
            }

            MessageBox.Show("Congratolation \n your path cost = " + PathCost + " \n your space = " + BFS.nodes.Count + "\n your time = " + time);
        }
Example #6
0
    public void PathFinderFunction(float _x, float _z, Vector3 unitPosition, ref List <Vector3> directionList, ref bool isAbleToReach) //_x와 _z는 목표점의 transform.position의 값들입니다.
    {
        // be returned value
        //List<Vector3>
        directionList = new List <Vector3>();

        float   myTx           = Mathf.Round(unitPosition.x);
        float   myTz           = Mathf.Round(unitPosition.z);
        Vector3 myUnitPosition = new Vector3(myTx, 1, myTz);

        openNodeDic   = new Dictionary <Vector3, myNode>();
        closedNodeDic = new Dictionary <Vector3, myNode>();

        //0.1   보이는 패쓰만 만듭니다.
        //0.11  보이는 패쓰만으로도 만들 수 없는지 여부를 판단합니다.
        //0.12  알 수없는 타일만으로 갈 수 있는지 여부도 판단합니다.
        //0.2   꺾는 곳마다 패쓰포인트에 기록합니다.


        // 열린 목록

        //0.1.
        // A* 알고리즘을 사용합니다.
        // 4개의 방향으로 리스트 만들기
        // 일단 좌표만 찍고, 각 부분에 벽이 있는지 바닥이 있는지 검사합니다.
        // 만약 바닥인 경우, 그 좌표는 이용 가능한 것으로 판정됩니다.
        // 이용 가능한 좌표들중에 이동한 타일 갯수, 목표지점과 현재 타일의 Dy+Dx의 값을 각각 기록합니다.
        // 가는 길이 없는 경우 100번 블럭도 허용합니다.
        //for(int i = 0, i > 1, i++)

        bool isUnitKnowRoute = true; // 이 변수는 초반에 아는 길로 PathFind하도록 합니다.

        // Pop
        if (checkBlockForPath(new Vector3(myTx + 1, 1, myTz), false))
        {
            openNodeDic.Add(new Vector3(myTx + 1, 1, myTz), new myNode(myTx + 1, myTz, _x, _z, 1, myUnitPosition));
        }
        if (checkBlockForPath(new Vector3(myTx - 1, 1, myTz), false))
        {
            openNodeDic.Add(new Vector3(myTx - 1, 1, myTz), new myNode(myTx - 1, myTz, _x, _z, 1, myUnitPosition));
        }
        if (checkBlockForPath(new Vector3(myTx, 1, myTz + 1), false))
        {
            openNodeDic.Add(new Vector3(myTx, 1, myTz + 1), new myNode(myTx, myTz + 1, _x, _z, 1, myUnitPosition));
        }
        if (checkBlockForPath(new Vector3(myTx, 1, myTz - 1), false))
        {
            openNodeDic.Add(new Vector3(myTx, 1, myTz - 1), new myNode(myTx, myTz - 1, _x, _z, 1, myUnitPosition));
        }

        while (true)
        {
            // 선택된 것은 가장 낮은 값이여야 합니다!
            // F값이 가장 낮은 값을 선정 <입력 완료>
            var tempMyNodeList = new List <myNode>(openNodeDic.Values);
            //myNode tempMyNode = tempMyNodeList.Find(tempval => tempval != null); // <<<< 문제
            myNode tempMyNode = tempMyNodeList[tempMyNodeList.FindIndex(LambdaMyNode => LambdaMyNode.deltaXZ >= 0)]; // 와일 문에서 사용되는 노드.

            foreach (myNode NodeInList in new List <myNode>(openNodeDic.Values))
            {
                if (tempMyNode.F > NodeInList.F)
                {
                    tempMyNode = NodeInList;
                }
            }
            // 열린 구간에서 빼내서 닫힌 구간에 넣기
            openNodeDic.Remove(tempMyNode.locate);
            closedNodeDic.Add(tempMyNode.locate, tempMyNode);////////////////////

            //if (tempMyNodeList.FindIndex(node => node.deltaXZ == 0) != -1) // 길을 찾았습니다. 목록 중에 DeltaXZ값이 0인 노드가 있습니다.
            if (tempMyNode.deltaXZ == 0)
            {
                //Debug.Log("길을 찾았습니다!");
                // 패스파인더를 통해 만들어진 이동 목록 만들기
                // a-1 deltaXZ가 0인 노드를 찾기
                // a-2 그 노드를 이동목록의 맨 첫번째에 넣기

                // a-3 perv가 (myTx, 1, myTy)인지 확인하기
                // a-4 그 노드의 멤버 perv를 키값으로 하여 closedNodeDic에서 찾아보기
                // 이 데이터를 단순한 방향을 배열한 정보로 변환한다 디렉션어레이라고 부르자

                List <myNode> moveList = new List <myNode>();
                for (myNode pickedMyNode = tempMyNodeList[tempMyNodeList.FindIndex(node => node.deltaXZ == 0)]; true;)
                {
                    directionList.Insert(0, pickedMyNode.locate - pickedMyNode.perv);
                    if (pickedMyNode.perv == myUnitPosition)
                    {
                        break;                                      // 이것은 맨 마지막 노드입니다.
                    }
                    try
                    {
                        pickedMyNode = closedNodeDic[pickedMyNode.perv]; // 노드의 과거를 따라 짚어갑니다.
                        //Debug.Log("헤헤 길 찾았아요!");
                    }
                    catch (KeyNotFoundException)
                    {
                        Debug.Log("ERROR_PathFinderFunction_값을 찾을 수 없습니다!");
                        break;
                    }
                }
                isAbleToReach = true;
                break;
                // 야호 드디어 길을 찾았어요!
                // 경로를 생성합니다.

                // 이동 명령은 클릭한 지 1초 뒤에 움직이도록 합니다.
                // 아마 스레드로 움직일테니 이벤트를 쓸 수 있으면 쓸 수 있도록 합니다.
                // 이벤트 활성화가 되지 않았으면 업데이트 함수에 이동 코드가 작동하지 않음
            }
            if ((openNodeDic.Count == 0) && isUnitKnowRoute) // 초기에는 모르는 길을 선택하지 않으니 pop위쪽에 놔둠.
            {
                Debug.Log("알고 있는 길을 찾을 수 없습니다!");
                isUnitKnowRoute = false;
                //break;
            }

            // Pop(가장 낮은)
            if (checkBlockForPath(new Vector3(tempMyNode.locate.x + 1, 1, tempMyNode.locate.z), isUnitKnowRoute))
            {
                openNodeDic.Add(new Vector3(tempMyNode.locate.x + 1, 1, tempMyNode.locate.z), new myNode(tempMyNode.locate.x + 1, tempMyNode.locate.z, _x, _z, tempMyNode.moveCount + 1, tempMyNode.locate));
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x + 1, tempMyNode.moveCount, tempMyNode.locate.z), Quaternion.identity);
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x + 1, 1.5f, tempMyNode.locate.z), Quaternion.identity);
            }
            if (checkBlockForPath(new Vector3(tempMyNode.locate.x - 1, 1, tempMyNode.locate.z), isUnitKnowRoute))
            {
                openNodeDic.Add(new Vector3(tempMyNode.locate.x - 1, 1, tempMyNode.locate.z), new myNode(tempMyNode.locate.x - 1, tempMyNode.locate.z, _x, _z, tempMyNode.moveCount + 1, tempMyNode.locate));
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x - 1, tempMyNode.moveCount, tempMyNode.locate.z), Quaternion.identity);
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x + 1, 1.5f, tempMyNode.locate.z), Quaternion.identity);
            }
            if (checkBlockForPath(new Vector3(tempMyNode.locate.x, 1, tempMyNode.locate.z + 1), isUnitKnowRoute))
            {
                openNodeDic.Add(new Vector3(tempMyNode.locate.x, 1, tempMyNode.locate.z + 1), new myNode(tempMyNode.locate.x, tempMyNode.locate.z + 1, _x, _z, tempMyNode.moveCount + 1, tempMyNode.locate));
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x, tempMyNode.moveCount, tempMyNode.locate.z + 1), Quaternion.identity);
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x + 1, 1.5f, tempMyNode.locate.z), Quaternion.identity);
            }
            if (checkBlockForPath(new Vector3(tempMyNode.locate.x, 1, tempMyNode.locate.z - 1), isUnitKnowRoute))
            {
                openNodeDic.Add(new Vector3(tempMyNode.locate.x, 1, tempMyNode.locate.z - 1), new myNode(tempMyNode.locate.x, tempMyNode.locate.z - 1, _x, _z, tempMyNode.moveCount + 1, tempMyNode.locate));
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x, tempMyNode.moveCount, tempMyNode.locate.z - 1), Quaternion.identity);
                //Instantiate(PathFinderGuide, new Vector3(tempMyNode.locate.x + 1, 1.5f, tempMyNode.locate.z), Quaternion.identity);
            }


            // 길이 없는 경우

            if ((openNodeDic.Count == 0) && !isUnitKnowRoute)
            {
                Debug.LogWarning("길을 찾을 수 없습니다!");
                isAbleToReach = false;
                break;
            }
        }
    }