Esempio n. 1
0
File: Node.cs Progetto: GotoK/H401
    // 隣接判定、ノードごとの処理
    public void NodeCheckAction(NodeController.NodeLinkTaskChecker Tc, _eLinkDir Link)
    {
        NodeDebugLog += "NodeCheckAction. CheckerID : " + Tc.ID + "\n";
        // チェック済みでスキップ
        if (bChecked) { Tc.Branch--; return; }

        // 各種変数定義
        bool bBranch = false;
        bChecked = true;
        Tc.SumNode++;
        bChain = false;

        // お隣さんを更新
        UpdateNegibor();

        // 状態表示
        Tc += (ToString() + "Action \n     Link : " + bitLink.ToStringEx() + "\nNegibor : " + Negibor.ToStringEx());
        Tc += Tc.NotFin + " : " + Tc.Branch.ToString();

        // チェックスタート
        // 接地判定(根本のみ)
        if (Link == _eLinkDir.NONE)     // 根本か確認
        {
            if (!bitLink[(int)_eLinkDir.RD] && !bitLink[(int)_eLinkDir.LD]) // 下方向チェック
            {
                Tc.Branch--;
                Tc.SumNode--;
                bChecked = false;
                return;                 // 繋がってないなら未チェックとして処理終了
            }
            // 繋がっている
            Tc += ("Ground");
        }

        // この時点で枝が繋がっている事が確定
        bChain = true;
        Tc.NodeList.Add(this);  // チェッカに自身を登録しておく

        // 終端ノードであれば、周囲チェック飛ばす
        var TempBit = new BitArray(6);
        // 除外方向設定
        TempBit.SetAll(false);
        if (Link == _eLinkDir.NONE)
        {
            TempBit.Set((int)_eLinkDir.RD, true);
            TempBit.Set((int)_eLinkDir.LD, true);
        }
        else {
            TempBit.Set((int)Link, true);
        }
        TempBit.And(bitLink).Xor(bitLink);    // 自身の道とAND後、自身の道とXOR。
        if (TempBit.isZero())                  // 比較して一致なら除外方向以外に道がない = XOR後に全0なら終端
        {
            Tc.Branch--;                      // 終端ノードであればそこで終了
            return;
        }

        // 周囲のチェック
        // この時点で、TempBitは先が壁の道を除いた自分の道を示している。
        Tc += "ExcludeFrom MyWay : " + TempBit.ToStringEx();

        for (int n = 0; n < (int)_eLinkDir.MAX; n++)
        {
            var TempBit2 = new BitArray(6);
            // 隣接ノードのうち、道が無い場所に自分の道が伸びてたらそこは途切れている。
            TempBit2 = TempBit.retAnd(Negibor.retNot());
            // ノード繋がってない
            if (TempBit2[n])
            {
                nodeControllerScript.unChainController.AddObj(this, (_eLinkDir)n);
                Tc.NotFin = true;                               // 隣と繋がってないので、枝未完成として登録
            }
        }

        Tc += ("Negibor : " + Negibor.ToStringEx());
        TempBit.And(Negibor);                       // 隣接ノードと繋がっている場所を特定
        Tc += "Linked : " + TempBit.ToStringEx();
        for (int n = 0; n < (int)_eLinkDir.MAX; n++)
        {
            if (!TempBit[n]) { continue; }          // ビット立ってないならスキップ

            // お隣さんと繋がっているので、処理引き渡しの準備
            bChain = true;

            // デバック表示
            Tc += ("Linked [" + LinkDirToString(n) + "]");

            // 接続先がおかしいならノーカンで
            Vec2Int Target = nodeControllerScript.GetDirNode(nodeID, (_eLinkDir)n);
            if (Target.x == -1) { continue; }

            // 分岐を検出してカウント
            if (!bBranch)
            {
                bBranch = true;     // 一回目ならノーカン
            }
            else {
                Tc.Branch++;        // 二回目以降は分岐なので、枝カウンタを+1
            }

            // 次へ引き渡す
            Node TgtNode = nodeControllerScript.GetNodeScript(Target);
            if (TgtNode.IsOutPuzzle)
            {
                Tc.Branch--;        // 接続先が壁なら処理飛ばして枝解決
            }
            else {
                // 周囲のActionをトリガーさせる
                Observable
                .Return(TgtNode)
                .Subscribe(_ => {
                    TgtNode.NodeCheckAction(Tc, (_eLinkDir)((n + 3 >= 6) ? (n + 3 - 6) : (n + 3)));
                }).AddTo(this);
            }
        }

        if (Tc.NotFin && Tc.Branch > 0)
        {
            Tc.Branch--;
        }
    }