Ejemplo n.º 1
0
        /// <summary>
        /// ノード生成する
        /// </summary>
        /// <param name="x">そのノードのx座標</param>
        /// <param name="y">そのノードのy座標</param>
        /// <returns></returns>
        public A_Node Get_Node(int x, int y)
        {
            // 目的地の1つ手前の座標を探す
            foreach (var before_one in goal_before_one)
            {
                if (x == goal_x || y == goal_y)
                {
                    allowdiag = false;
                }
            }

            int idx = layer.To_Index(x, y);

            if (pool.ContainsKey(idx))
            {
                // 既に存在しているのでプーリングから取得
                return(pool[idx]);
            }

            // ないので新規作成
            var node = new A_Node(x, y);

            pool[idx] = node;
            // ヒューリスティック・コストを計算する
            node.Calc_Heuristic(allowdiag, goal_x, goal_y);
            return(node);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 指定の座標にあるノードをオープンする
        /// </summary>
        /// <param name="x"     >オープンするノードの座標</param>
        /// <param name="y"     >オープンするノードの座標</param>
        /// <param name="cost"  >オープンするノードのコスト</param>
        /// <param name="parent">親ノード</param>
        /// <returns>オープンしたノード</returns>
        public A_Node Open_Node(int x, int y, int cost, A_Node parent)
        {
            // 座標をチェック
            if (layer.Is_Out_Of_Range(x, y))
            {
                // 領域外
                return(null);
            }
            if (layer.Get(x, y) > 1)
            {
                // 通過できない
                return(null);
            }
            // ノードを取得する
            A_Node node = Get_Node(x, y);

            if (node.Is_None() == false)
            {
                // 既にOpenしているので何もしない
                return(null);
            }

            // Openする
            node.Open(parent, cost);

            Add_Open_List(node);

            return(node);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 最小スコアのノードを取得する
        /// </summary>
        /// <returns>最小スコアのノード</returns>
        public A_Node Search_Min_Score_Node()
        {
            // 最小スコア
            int min = 9999;
            // 最小実コスト
            int    min_cost = 9999;
            A_Node min_node = null;

            foreach (A_Node node in open_list)
            {
                int score = node.GetScore();
                if (score > min)
                {
                    // スコアが大きい
                    continue;
                }
                if (score == min && node.Cost >= min_cost)
                {
                    // スコアが同じときは実コストも比較する
                    continue;
                }
                // 最小値更新.
                min      = score;
                min_cost = node.Cost;
                min_node = node;
            }
            return(min_node);
        }
Ejemplo n.º 4
0
    void ConnectNodes()
    {
        int nodeCounter = 0;

        foreach (A_Node node in nodes)
        {
            A_Node tmp = SearchForNode(new Vector3(node.position.x, node.position.y, node.position.z - 1));
            if (tmp != null)
            {
                node.connections.Add(tmp);
            }
            tmp = SearchForNode(new Vector3(node.position.x, node.position.y, node.position.z + 1));
            if (tmp != null)
            {
                node.connections.Add(tmp);
            }
            tmp = SearchForNode(new Vector3(node.position.x - 1, node.position.y, node.position.z));
            if (tmp != null)
            {
                node.connections.Add(tmp);
            }
            tmp = SearchForNode(new Vector3(node.position.x + 1, node.position.y, node.position.z));
            if (tmp != null)
            {
                node.connections.Add(tmp);
            }
            nodeCounter++;
        }
    }
Ejemplo n.º 5
0
 void SortNodes(List <A_Node> items)
 {
     if (items.Count > 0)
     {
         bool isSorted  = false;
         int  lUnsorted = items.Count;
         while (!isSorted)
         {
             isSorted = true;
             for (int i = 0; i < lUnsorted; i++)
             {
                 if (i + 1 < items.Count)
                 {
                     items[i].CalF();
                     items[i + 1].CalF();
                     if (items[i + 1].f_score < items[i].f_score)
                     {
                         A_Node tmp = items[i + 1];
                         items[i + 1] = items[i];
                         items[i]     = tmp;
                     }
                 }
             }
             lUnsorted--;
         }
     }
 }
Ejemplo n.º 6
0
    void MakeNodes()
    {
        Collider[] coll;
        bool       waitForNext  = false;
        bool       doPlayerOnce = false;
        bool       doTargetOnce = false;
        Vector3    lastNodePos  = Vector3.zero;
        int        currNode     = 0;

        for (float i = -size.x; i < size.x; i++)
        {
            for (float j = -size.z; j < size.z; j++)
            {
                coll = Physics.OverlapBox(new Vector3(i, size.y, j), sizeOfBox / 2);
                foreach (Collider col in coll)
                {
                    foreach (string tag in tags)
                    {
                        if (col.gameObject.CompareTag(tag) && !waitForNext)
                        {
                            nodes.Add(new A_Node(2, new Vector3(i, size.y, j)));
                            waitForNext = true;
                        }
                    }
                    if (col.gameObject.CompareTag(this.gameObject.tag) && !waitForNext)
                    {
                        if (!doPlayerOnce)
                        {
                            nodes.Add(new A_Node(0, new Vector3(i, size.y, j)));
                            startNode    = nodes[currNode];
                            waitForNext  = true;
                            doPlayerOnce = true;
                        }
                    }
                    if (col.gameObject.CompareTag(target.gameObject.tag) && !waitForNext)
                    {
                        if (!doTargetOnce)
                        {
                            nodes.Add(new A_Node(-1, new Vector3(i, size.y, j)));
                            targetNode   = nodes[currNode];
                            waitForNext  = true;
                            doTargetOnce = true;
                        }
                    }
                }
                if (!waitForNext)
                {
                    nodes.Add(new A_Node(1, new Vector3(i, size.y, j)));
                }
                currNode++;
                waitForNext = false;
            }
        }
        foreach (A_Node node in nodes)
        {
            node.h_score = (node.position.x + targetNode.position.x) + (node.position.z + targetNode.position.z);
        }
        ConnectNodes();
    }
Ejemplo n.º 7
0
    void ReValueNodes()
    {
        Collider[] coll;
        bool       waitForNext  = false;
        bool       doPlayerOnce = false;
        bool       doTargetOnce = false;
        Vector3    lastNodePos  = Vector3.zero;

        foreach (A_Node node in nodes)
        {
            coll = Physics.OverlapBox(node.position, sizeOfBox / 2);
            foreach (Collider col in coll)
            {
                foreach (string tag in tags)
                {
                    if (col.gameObject.CompareTag(tag) && !waitForNext)
                    {
                        node.g_score = 2;
                        waitForNext  = true;
                    }
                }
                if (col.gameObject.CompareTag(this.gameObject.tag) && !waitForNext)
                {
                    if (!doPlayerOnce)
                    {
                        node.g_score       = 0;
                        startNode          = node;
                        waitForNext        = true;
                        doPlayerOnce       = true;
                        transform.position = node.position;
                    }
                }
                if (col.gameObject.CompareTag(target.gameObject.tag) && !waitForNext)
                {
                    if (!doTargetOnce)
                    {
                        node.g_score       = -1;
                        targetNode         = node;
                        waitForNext        = true;
                        doTargetOnce       = true;
                        transform.position = node.position;
                    }
                }
            }
            if (!waitForNext)
            {
                node.g_score = 1;
            }
            node.pastNode = null;
            waitForNext   = false;
        }
        foreach (A_Node node in nodes)
        {
            node.h_score = (node.position.x + targetNode.position.x) + (node.position.z + targetNode.position.z);
        }
    }
Ejemplo n.º 8
0
 bool isInClosesd(A_Node value)
 {
     for (int i = 0; i < closedList.Count; i++)
     {
         if (closedList[i] == value)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 9
0
 bool isInOpen(A_Node value)
 {
     for (int i = 0; i < openList.Count; i++)
     {
         if (openList[i] == value)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 10
0
    void LookForPath()
    {
        // do some sort of for loop in here
        currentNode = startNode;
        bool pathFound  = false;
        int  operations = 0;

        while (!pathFound)
        {
            if (!isInClosesd(currentNode))
            {
                closedList.Add(currentNode);
            }
            for (int i = 0; i < currentNode.connections.Count; i++)
            {
                if (!isInOpen(currentNode.connections[i]) && !isInClosesd(currentNode.connections[i]))
                {
                    currentNode.connections[i].g_score += currentNode.g_score;
                    if (currentNode.connections[i].pastNode == null)
                    {
                        currentNode.connections[i].pastNode = currentNode;
                    }
                    openList.Add(currentNode.connections[i]);
                }
            }
            SortNodes(openList);
            if (openList.Count > 0)
            {
                currentNode = openList[0];
                openList.Remove(currentNode);
            }
            if (currentNode == targetNode)
            {
                pathFound = true;
            }
            operations++;
        }
        Debug.Log(operations);
        pathFound = false;
        while (!pathFound)
        {
            if (currentNode != null)
            {
                path.Add(currentNode);
                currentNode = currentNode.pastNode;
            }
            else
            {
                pathFound = true;
            }
        }
    }
Ejemplo n.º 11
0
 void CreatePath()
 {
     targetNode = null;
     startNode  = null;
     //RemoveAll(nodes);
     RemoveAll(openList);
     RemoveAll(closedList);
     RemoveAll(path);
     currentNode = null;
     startNode   = null;
     targetNode  = null;
     if (nodes.Count > 0)
     {
         ReValueNodes();
     }
     else
     {
         MakeNodes();
     }
     LookForPath();
     nextPath = path.Count - 1;
 }
Ejemplo n.º 12
0
        /// <summary>
        /// 周囲をOpenする
        /// </summary>
        /// <param name="parent"></param>
        public void Open_Around(A_Node parent)
        {
            // 基準座標(X)
            int xbase = parent.X;
            // 基準座標(Y)
            int ybase = parent.Y;
            // コスト
            int cost = parent.Cost;

            // 一歩進むので+1する
            cost += Define_Value.TILE_SCALE;
            if (allowdiag)
            {
                // 8方向を開く
                for (int j = 0; j <= 4; ++j)
                {
                    for (int i = 0; i <= 4; ++i)
                    {
                        int x = xbase + i - Define_Value.TILE_SCALE; // -1~1
                        int y = ybase + j - Define_Value.TILE_SCALE; // -1~1
                        Open_Node(x, y, cost, parent);
                    }
                }
            }
            else
            {
                // 4方向を開く
                var x = xbase;
                var y = ybase;
                // 上から時計回り
                Open_Node(x, y - Define_Value.TILE_SCALE, cost, parent);
                Open_Node(x - Define_Value.TILE_SCALE, y, cost, parent);
                Open_Node(x, y + Define_Value.TILE_SCALE, cost, parent);
                Open_Node(x + Define_Value.TILE_SCALE, y, cost, parent);
            }
        }
Ejemplo n.º 13
0
    /// <summary>
    /// 部屋にいるときの移動を管理
    /// </summary>
    public void Stack_List()
    {
        // 現在の座標を取得
        Point2 start = Get_Now_Position(enemy_object.GetComponent <Enemy>());
        // 指定の部屋の入口(出口)を探す
        Point2 goal = Get_Goal_Position(now_room_number);

        // 入口(出口)の1つ前の座標を取得
        goal_before_one = new List <Point2>();
        Get_Goal_Before_One(goal);

        if (goal_before_one.Count == 0)
        {
            Debug.Log("入り口前取れてない");
        }

        // 今いる座標
        var start_position = new Vector2Int {
            x = start.x,
            y = start.y
        };

        // 今いる部屋の中の座標に置き換える
        start_position = In_Room_Coodinates(start_position);
        // 目的地の座標
        goal_position = new Vector2Int {
            x = goal.x,
            y = goal.y
        };
        // 今いる部屋の中の座標に置き換える
        goal_position = In_Room_Coodinates(goal_position);

        // 座標を知ってる構造体のリスト
        point_list = new List <Point2>();

        // 斜め移動を許可
        var allowdiag    = true;
        var node_manager = new A_Node_Manager(now_room_number, goal.x, goal.y, goal_before_one, allowdiag);

        // スタート地点のノード取得
        // スタート地点なのでコストは「0」
        A_Node node = node_manager.Open_Node((int)start_position.x, (int)start_position.y, 0, null);

        node_manager.Add_Open_List(node);

        // 試行回数
        int counter = 0;

        while (counter < 10)   //TODO:マジックナンバー
        {
            node_manager.Remove_Open_List(node);
            // 周囲を開く
            node_manager.Open_Around(node);
            // 最小スコアのノードを探す.
            node = node_manager.Search_Min_Score_Node();
            if (node == null)
            {
                // 袋小路なのでおしまい.
                break;
            }
            // ゴールにたどり着いた // TODO:たどり着かない場合がある。
            if (node.X == goal_position.x && node.Y == goal_position.y)
            {
                node_manager.Remove_Open_List(node);
                // パスを取得する
                node.GetPath(point_list);
                // 反転する
                point_list.Reverse();
                break;
            }
        }
    }
Ejemplo n.º 14
0
 void CheckNodes(A_Node a, A_Node b)
 {
 }
Ejemplo n.º 15
0
 /// <summary>
 /// ノードをオープンリストから削除する
 /// </summary>
 /// <param name="node">不要ノード</param>
 public void Remove_Open_List(A_Node node)
 {
     open_list.Remove(node);
 }
Ejemplo n.º 16
0
 /// <summary>
 /// ノードをオープンリストに追加する
 /// </summary>
 /// <param name="node">オープンにしたノード</param>
 public void Add_Open_List(A_Node node)
 {
     open_list.Add(node);
 }
Ejemplo n.º 17
0
 /// <summary>
 /// ステータスをOpenにする
 /// </summary>
 /// <param name="parent_">親ノード</param>
 /// <param name="cost_">次開けるもののコスト</param>
 public void Open(A_Node set_parent, int set_cost)
 {
     status = eNode_Status.Open;
     cost   = set_cost;
     parent = set_parent;
 }