Пример #1
0
        public PathList[] GetPath(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int Accuracy, int MinClearance)
        {
            int StartNodeCount = StartNodes.GetUpperBound(0) + 1;
            PathList[] Paths = new PathList[NodeLayerCount];
            PathfinderNode[,] LayerStartNodes = new PathfinderNode[NodeLayerCount, StartNodeCount];
            PathfinderNode[] LayerFinishNodes = new PathfinderNode[NodeLayerCount];
            int LayerNum = 0;
            PathfinderNode[] Destinations = new PathfinderNode[24];
            int DestinationCount = 0;
            bool FinishIsParent = default(bool);
            bool IsInaccurate;
            int[] CalcNodeCount = new int[24];
            sFloodRouteArgs FloodRouteArgs = new sFloodRouteArgs();
            int FinalLayer = 0;
            bool[] StartCanReach = new bool[StartNodeCount];
            PathfinderNode tmpNodeA = default(PathfinderNode);
            PathfinderNode tmpNodeB = default(PathfinderNode);
            int CanReachCount = 0;
            int FirstLayer = 0;
            Path[] BestPaths = new Path[24];
            float[] BestValues = new float[24];
            int PathNum = 0;
            bool StopMultiPathing = default(bool);
            bool[] Visit = NetworkLargeArrays.Nodes_Booleans;
            float[] NodeValues = NetworkLargeArrays.Nodes_ValuesA;
            PathfinderNode[] Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes;
            Path StartPath = NetworkLargeArrays.Nodes_Path;
            int A = 0;
            int B = 0;
            int C = 0;
            int D = 0;
            int E = 0;

            FinalLayer = StartNodes[0].Layer.Network_LayerNum;
            LayerFinishNodes[FinalLayer] = FinishNode;
            B = FinalLayer;
            do
            {
                if ( LayerFinishNodes[B].ParentNode == null )
                {
                    FirstLayer = B;
                    break;
                }
                LayerFinishNodes[B + 1] = LayerFinishNodes[B].ParentNode;
                B++;
            } while ( true );
            for ( A = 0; A <= StartNodeCount - 1; A++ )
            {
                LayerStartNodes[FinalLayer, A] = StartNodes[A];
                B = FinalLayer;
                do
                {
                    if ( LayerStartNodes[B, A].ParentNode == null )
                    {
                        if ( LayerStartNodes[B, A] == LayerFinishNodes[B] )
                        {
                            StartCanReach[A] = true;
                            CanReachCount++;
                        }
                        break;
                    }
                    LayerStartNodes[B + 1, A] = LayerStartNodes[B, A].ParentNode;
                    B++;
                } while ( true );
            }
            if ( CanReachCount == 0 )
            {
                return null;
            }
            LayerNum = FirstLayer;
            Paths[LayerNum].Paths = new Path[0];
            Paths[LayerNum].Paths[0] = new Path();
            Paths[LayerNum].PathCount = 1;
            Paths[LayerNum].Paths[0].Nodes = new PathfinderNode[1];
            Paths[LayerNum].Paths[0].Nodes[0] = LayerFinishNodes[LayerNum];
            Paths[LayerNum].Paths[0].NodeCount = 1;
            int LastLayer = 0;
            do
            {
                LastLayer = LayerNum;
                LayerNum--;
                if ( LayerNum < FinalLayer )
                {
                    break;
                }
                else if ( StopMultiPathing )
                {
                    if ( Accuracy < 0 )
                    {
                        Debugger.Break();
                    }
                    for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ )
                    {
                        CalcNodeCount[PathNum] = Math.Min(Accuracy, Convert.ToInt32(Paths[LastLayer].Paths[PathNum].NodeCount - 1));
                    }
                    Destinations[0] = Paths[LastLayer].Paths[0].Nodes[CalcNodeCount[0]];
                    DestinationCount = 1;
                    FinishIsParent = true;
                    IsInaccurate = true;
                }
                else
                {
                    if ( Accuracy >= 0 )
                    {
                        for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ )
                        {
                            if ( Paths[LastLayer].Paths[PathNum].NodeCount > Accuracy )
                            {
                                StopMultiPathing = true;
                                break;
                            }
                        }
                    }
                    Destinations[0] = LayerFinishNodes[LayerNum];
                    if ( LayerNum == FinalLayer )
                    {
                        DestinationCount = 1;
                    }
                    else
                    {
                        for ( A = 0; A <= Destinations[0].ConnectionCount - 1; A++ )
                        {
                            Destinations[1 + A] = Destinations[0].Connections[A].GetOtherNode(Destinations[0]);
                        }
                        DestinationCount = 1 + Destinations[0].ConnectionCount;
                    }
                    for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ )
                    {
                        CalcNodeCount[PathNum] = Paths[LastLayer].Paths[PathNum].NodeCount - 1;
                    }
                    FinishIsParent = false;
                }
                for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ )
                {
                    for ( A = 0; A <= CalcNodeCount[PathNum]; A++ )
                    {
                        tmpNodeA = Paths[LastLayer].Paths[PathNum].Nodes[A];
                        for ( D = 0; D <= tmpNodeA.ConnectionCount - 1; D++ )
                        {
                            tmpNodeB = tmpNodeA.Connections[D].GetOtherNode(tmpNodeA);
                            for ( E = 0; E <= tmpNodeB.ConnectionCount - 1; E++ )
                            {
                                C = tmpNodeB.Connections[E].GetOtherNode(tmpNodeB).Layer_NodeNum;
                                Visit[C] = false;
                            }
                        }
                    }
                }
                for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ )
                {
                    for ( A = 0; A <= CalcNodeCount[PathNum]; A++ )
                    {
                        tmpNodeA = Paths[LastLayer].Paths[PathNum].Nodes[A];
                        C = tmpNodeA.Layer_NodeNum;
                        Visit[C] = true;
                        for ( E = 0; E <= tmpNodeA.NodeCount - 1; E++ )
                        {
                            C = tmpNodeA.Nodes[E].Layer_NodeNum;
                            NodeValues[C] = float.MaxValue;
                        }
                        for ( D = 0; D <= tmpNodeA.ConnectionCount - 1; D++ )
                        {
                            tmpNodeB = tmpNodeA.Connections[D].GetOtherNode(tmpNodeA);
                            C = tmpNodeB.Layer_NodeNum;
                            Visit[C] = true;
                            for ( E = 0; E <= tmpNodeB.NodeCount - 1; E++ )
                            {
                                C = tmpNodeB.Nodes[E].Layer_NodeNum;
                                NodeValues[C] = float.MaxValue;
                            }
                        }
                    }
                }
                FloodRouteArgs = new sFloodRouteArgs();
                FloodRouteArgs.CurrentPath = StartPath;
                FloodRouteArgs.FinishNodes = Destinations;
                FloodRouteArgs.FinishNodeCount = DestinationCount;
                FloodRouteArgs.FinishIsParent = FinishIsParent;
                FloodRouteArgs.Visit = Visit;
                FloodRouteArgs.NodeValues = NodeValues;
                FloodRouteArgs.SourceNodes = Nodes_Nodes;
                FloodRouteArgs.MinClearance = MinClearance;
                for ( A = 0; A <= DestinationCount - 1; A++ )
                {
                    BestPaths[A] = null;
                    BestValues[A] = float.MaxValue;
                }
                for ( A = 0; A <= StartNodeCount - 1; A++ )
                {
                    if ( StartCanReach[A] )
                    {
                        StartPath.NodeCount = 1;
                        StartPath.Nodes[0] = LayerStartNodes[LayerNum, A];
                        StartPath.Value = 0.0F;
                        FloodRouteArgs.BestPaths = new Path[DestinationCount];
                        FloodRoute(FloodRouteArgs);
                        for ( PathNum = 0; PathNum <= DestinationCount - 1; PathNum++ )
                        {
                            if ( FloodRouteArgs.BestPaths[PathNum] != null )
                            {
                                if ( FloodRouteArgs.BestPaths[PathNum].Value < BestValues[PathNum] )
                                {
                                    BestValues[PathNum] = FloodRouteArgs.BestPaths[PathNum].Value;
                                    BestPaths[PathNum] = FloodRouteArgs.BestPaths[PathNum];
                                }
                            }
                        }
                    }
                }
                Paths[LayerNum].Paths = new Path[DestinationCount];
                Paths[LayerNum].PathCount = 0;
                for ( PathNum = 0; PathNum <= DestinationCount - 1; PathNum++ )
                {
                    if ( BestPaths[PathNum] != null )
                    {
                        Paths[LayerNum].Paths[Paths[LayerNum].PathCount] = BestPaths[PathNum];
                        Paths[LayerNum].PathCount++;
                    }
                }
                Array.Resize(ref Paths[LayerNum].Paths, Paths[LayerNum].PathCount);
                if ( Paths[LayerNum].PathCount == 0 )
                {
                    return null;
                }
            } while ( true );
            return Paths;
        }
Пример #2
0
        public Path[] GetAllPaths(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int MinClearance)
        {
            int StartNodeCount = StartNodes.GetUpperBound(0) + 1;
            PathfinderNode[,] LayerStartNodes = new PathfinderNode[32, StartNodeCount];
            PathfinderNode[] LayerFinishNodes = new PathfinderNode[32];
            int LayerNum = 0;
            PathfinderNode[] Destinations = new PathfinderNode[24];
            sFloodRouteAllArgs FloodRouteDArgs = new sFloodRouteAllArgs();
            int FinalLayer = 0;
            bool[] StartCanReach = new bool[StartNodeCount];
            PathfinderNode tmpNodeA = default(PathfinderNode);
            int CanReachCount = 0;
            int FirstLayer = 0;
            Path[] SubPaths = new Path[32];
            PathfinderNode[] Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes;
            bool[] Visit = NetworkLargeArrays.Nodes_Booleans;
            float[] NodeValues = NetworkLargeArrays.Nodes_ValuesA;
            float[] NodeValuesB = NetworkLargeArrays.Nodes_ValuesB;
            int A = 0;
            int B = 0;
            int C = 0;
            int D = 0;

            FinalLayer = StartNodes[0].Layer.Network_LayerNum;
            LayerFinishNodes[FinalLayer] = FinishNode;
            B = FinalLayer;
            do
            {
                if ( LayerFinishNodes[B].ParentNode == null )
                {
                    FirstLayer = B;
                    break;
                }
                LayerFinishNodes[B + 1] = LayerFinishNodes[B].ParentNode;
                B++;
            } while ( true );
            for ( A = 0; A <= StartNodeCount - 1; A++ )
            {
                LayerStartNodes[FinalLayer, A] = StartNodes[A];
                B = FinalLayer;
                do
                {
                    if ( LayerStartNodes[B, A].ParentNode == null )
                    {
                        if ( LayerStartNodes[B, A] == LayerFinishNodes[B] )
                        {
                            StartCanReach[A] = true;
                            CanReachCount++;
                        }
                        break;
                    }
                    LayerStartNodes[B + 1, A] = LayerStartNodes[B, A].ParentNode;
                    B++;
                } while ( true );
            }
            if ( CanReachCount == 0 )
            {
                return null;
            }
            LayerNum = FirstLayer;
            SubPaths[LayerNum] = new Path();
            SubPaths[LayerNum].Nodes = new[] {LayerFinishNodes[LayerNum]};
            SubPaths[LayerNum].NodeCount = 1;
            int LastLayer = 0;
            do
            {
                LastLayer = LayerNum;
                LayerNum--;
                if ( LayerNum < FinalLayer )
                {
                    break;
                }
                for ( A = 0; A <= SubPaths[LastLayer].NodeCount - 1; A++ )
                {
                    tmpNodeA = SubPaths[LastLayer].Nodes[A];
                    for ( B = 0; B <= tmpNodeA.ConnectionCount - 1; B++ )
                    {
                        C = tmpNodeA.Connections[B].GetOtherNode(tmpNodeA).Layer_NodeNum;
                        Visit[C] = false;
                    }
                }
                for ( A = 0; A <= SubPaths[LastLayer].NodeCount - 1; A++ )
                {
                    tmpNodeA = SubPaths[LastLayer].Nodes[A];
                    C = tmpNodeA.Layer_NodeNum;
                    Visit[C] = true;
                    for ( D = 0; D <= tmpNodeA.NodeCount - 1; D++ )
                    {
                        C = tmpNodeA.Nodes[D].Layer_NodeNum;
                        NodeValues[C] = float.MaxValue;
                        NodeValuesB[C] = float.MaxValue;
                    }
                }
                FloodRouteDArgs = new sFloodRouteAllArgs();
                FloodRouteDArgs.FinishNode = LayerFinishNodes[LayerNum];
                FloodRouteDArgs.Visit = Visit;
                FloodRouteDArgs.NodeValuesA = NodeValues;
                FloodRouteDArgs.SourceNodes = Nodes_Nodes;
                FloodRouteDArgs.NodeValuesB = NodeValuesB;
                FloodRouteDArgs.MinClearance = MinClearance;
                FloodRouteDArgs.BestTolerance = (float)(Math.Pow(1.1D, LayerNum));
                FloodRouteDArgs.StartNodes = new PathfinderNode[StartNodeCount];
                for ( A = 0; A <= StartNodeCount - 1; A++ )
                {
                    if ( StartCanReach[A] )
                    {
                        FloodRouteDArgs.StartNodes[FloodRouteDArgs.StartNodeCount] = LayerStartNodes[LayerNum, A];
                        FloodRouteDArgs.StartNodeCount++;
                    }
                }
                Array.Resize(ref FloodRouteDArgs.StartNodes, FloodRouteDArgs.StartNodeCount);
                FloodRouteAll(FloodRouteDArgs);
                SubPaths[LayerNum] = new Path();
                SubPaths[LayerNum].Nodes = new PathfinderNode[FloodRouteDArgs.BestNodeCount];
                for ( A = 0; A <= FloodRouteDArgs.BestNodeCount - 1; A++ )
                {
                    SubPaths[LayerNum].Nodes[A] = FloodRouteDArgs.SourceNodes[A];
                }
                SubPaths[LayerNum].NodeCount = FloodRouteDArgs.BestNodeCount;
                if ( FloodRouteDArgs.BestNodeCount == 0 )
                {
                    Debugger.Break();
                    return SubPaths;
                }
            } while ( true );
            return SubPaths;
        }