コード例 #1
0
        private void StepOn(LibPF.Grid grid, LibPF.Finder.MinHeap open, LibPF.Position[] cameFrom, float[] costSoFar, LibPF.Offset[] movementPattern, LibPF.Position current, LibPF.Position end)
        {
            float initialCost = costSoFar[grid.GetIndexUnchecked(current.X, current.Y)];

            foreach (LibPF.Offset option in this.GetMovementOptions(current, grid.DimX, grid.DimY, movementPattern))
            {
                LibPF.Position position = current + option;
                float          cellCost = grid.GetCellCostUnchecked(position);
                if (float.IsInfinity(cellCost))
                {
                    continue;
                }
                int   index   = grid.GetIndexUnchecked(position.X, position.Y);
                float newCost = initialCost + cellCost * option.Cost;
                float oldCost = costSoFar[index];
                if (!(oldCost <= 0) && !(newCost < oldCost))
                {
                    continue;
                }
                costSoFar[index] = newCost;
                cameFrom[index]  = current;
                newCost          = newCost + this.ManhattanDistance(position, end);
                open.Push(new LibPF.Finder.MinHeapNode(position, newCost));
#if DEBUG
                this.MessageOpen(position);
#endif
            }
        }
コード例 #2
0
        public SysClG.List <LibPF.Position> FindPath(LibPF.Grid grid, LibPF.Position start, LibPF.Position end, LibPF.Offset[] movementPattern, int iterationLimit)
        {
#if DEBUG
            this.ClearStepList();
#endif
            if (start == end)
            {
                return(new SysClG.List <LibPF.Position> {
                    start
                });
            }
            LibPF.Finder.MinHeapNode head = new LibPF.Finder.MinHeapNode(start, this.ManhattanDistance(start, end));
            LibPF.Finder.MinHeap     open = new LibPF.Finder.MinHeap();
            open.Push(head);
            float[]          costSoFar = new float[grid.DimX * grid.DimY];
            LibPF.Position[] cameFrom  = new LibPF.Position[grid.DimX * grid.DimY];
            while (open.HasNext() && iterationLimit > 0)
            {
                LibPF.Position current = open.Pop().Position;
#if DEBUG
                this.MessageCurrent(current, this.PartiallyReconstructPath(grid, start, current, cameFrom));
#endif
                if (current == end)
                {
                    return(this.ReconstructPath(grid, start, end, cameFrom));
                }
                this.StepOn(grid, open, cameFrom, costSoFar, movementPattern, current, end);
#if DEBUG
                this.MessageClose(current);
#endif
                --iterationLimit;
            }
            return(null);
        }
コード例 #3
0
 private SysClG.IEnumerable <LibPF.Offset> GetMovementOptions(LibPF.Position position, int dimX, int dimY, SysClG.IEnumerable <LibPF.Offset> movementPattern)
 {
     LibPF.Position target = default(LibPF.Position);
     foreach (LibPF.Offset m in movementPattern)
     {
         target = position + m;
         if (target.X >= 0 && target.X < dimX && target.Y >= 0 && target.Y < dimY)
         {
             yield return(m);
         }
     }
 }
コード例 #4
0
 private SysClG.List <LibPF.Position> ReconstructPath(LibPF.Grid grid, LibPF.Position start, LibPF.Position end, LibPF.Position[] cameFrom)
 {
     SysClG.List <LibPF.Position> path = new SysClG.List <LibPF.Position> {
         end
     };
     LibPF.Position current = end;
     do
     {
         LibPF.Position previous = cameFrom[grid.GetIndexUnchecked(current.X, current.Y)];
         current = previous;
         path.Add(current);
     } while (current != start);
     return(path);
 }
コード例 #5
0
 public LibPF.Position[] GetPath(LibPF.Position start, LibPF.Position end, LibPF.Offset[] movementPattern, int iterationLimit)
 {
     SysClG.List <LibPF.Position> current = null;
     using (LibPF.Finder finder = new LibPF.Finder()) { current = finder.FindPath(this, start, end, movementPattern, iterationLimit); }
     if (current == null)
     {
         return(new LibPF.Position[0]);
     }
     else
     {
         LibPF.Position[] ar = new LibPF.Position[current.Count];
         int idx             = current.Count - 1;
         foreach (LibPF.Position step in current)
         {
             ar[idx] = step;
             idx--;
         }
         return(ar);
     }
 }
コード例 #6
0
 /* https://www.dotnetperls.com/aggressiveinlining , https://stackoverflow.com/questions/43060376/aggressiveinlining-doesnt-exist */ [SysCoS.MethodImpl(256)] private float ManhattanDistance(LibPF.Position p0, LibPF.Position p1)
 {
     return(Sys.Math.Abs(p0.X - p1.X) + Sys.Math.Abs(p0.Y - p1.Y));
 }
コード例 #7
0
 private void MessageCurrent(LibPF.Position position, SysClG.List <LibPF.Position> path)
 {
     this.StepList.Add(new LibPF.Finder.Step(LibPF.Finder.StepType.Current, position, path));
 }
コード例 #8
0
 private void MessageClose(LibPF.Position position)
 {
     this.StepList.Add(new Step(LibPF.Finder.StepType.Close, position, new SysClG.List <LibPF.Position>(0)));
 }
コード例 #9
0
 private void MessageOpen(LibPF.Position position)
 {
     this.StepList.Add(new LibPF.Finder.Step(LibPF.Finder.StepType.Open, position, new SysClG.List <LibPF.Position>(0)));
 }
コード例 #10
0
 public float GetCellCost(LibPF.Position position)
 {
     return(this.GetCellCost(position.X, position.Y));
 }
コード例 #11
0
 public LibPF.Position[] GetPath(LibPF.Position start, LibPF.Position end, LibPF.Offset[] movementPattern)
 {
     return(this.GetPath(start, end, movementPattern, int.MaxValue));
 }
コード例 #12
0
 public LibPF.Position[] GetPath(LibPF.Position start, LibPF.Position end)
 {
     return(this.GetPath(start, end, LibPF.MovementPatterns.Full));
 }
コード例 #13
0
 internal float GetCellCostUnchecked(LibPF.Position position)
 {
     return(this.Weights[this.GetIndexUnchecked(position.X, position.Y)]);
 }
コード例 #14
0
 public void UnblockCell(LibPF.Position position)
 {
     this.SetCellCost(position.X, position.Y, this.DefaultCost);
 }
コード例 #15
0
 public void BlockCell(LibPF.Position position)
 {
     this.BlockCell(position.X, position.Y);
 }
コード例 #16
0
 public Step(LibPF.Finder.StepType type, LibPF.Position position, SysClG.List <LibPF.Position> path)
 {
     this.Type     = type;
     this.Position = position;
     this.Path     = path;
 }
コード例 #17
0
 public MinHeapNode(LibPF.Position position, float expectedCost)
 {
     this.Position     = position;
     this.ExpectedCost = expectedCost;
 }
コード例 #18
0
    public static void Run(int SizeX, int SizeY, LibPF.Position start, LibPF.Position end, params LibPF.Position[] blocks)
    {
        if (SizeX > 99)
        {
            SizeX = 99;
        }
        if (SizeY > 99)
        {
            SizeY = 99;
        }
        LibPF.Grid g = new LibPF.Grid(SizeX, SizeY, defaultCost: 1.0f);
        foreach (LibPF.Position block in blocks)
        {
            g.BlockCell(block);
        }
        long   preTime = Sys.DateTime.Now.Ticks;
        string AUX     = g.ToJSon();

        g.Reset(1, 1, defaultCost: 1.0f);
        g.FromJSon(AUX);
        if (g.ToJSon() == AUX)
        {
            long posTime = Sys.DateTime.Now.Ticks;
            AUX = string.Empty;
            Sys.Console.Write("Time (JSon Conversion): " + Sys.TimeSpan.FromTicks(posTime - preTime).ToString());
            Sys.Console.WriteLine();
            preTime = Sys.DateTime.Now.Ticks;
            LibPF.Position[] path = g.GetPath(start, end, LibPF.MovementPatterns.Full);
            posTime = Sys.DateTime.Now.Ticks;
            Sys.Console.WriteLine("Time (Find Path): " + Sys.TimeSpan.FromTicks(posTime - preTime).ToString());
            preTime = Sys.DateTime.Now.Ticks;
            Sys.Console.WriteLine();
            Sys.Console.WriteLine();
            Sys.Console.Write(" _");
            for (int x = 0; x < SizeX; x++)
            {
                Sys.Console.Write("_" + ((x < 10) ? ("_" + x.ToString()) : x.ToString()) + "___");
            }
            Sys.Console.WriteLine();
            Sys.ConsoleColor stdColor = Sys.Console.ForegroundColor;
            Mn.Used          IsUsed   = Mn.Used.Not;
            for (int y = 0; y < SizeY; y++)
            {
                Sys.Console.Write(" |");
                for (int x = 0; x < SizeX; x++)
                {
                    Sys.Console.Write("     |");
                }
                Sys.Console.WriteLine();
                Sys.Console.Write(" |");
                for (int x = 0; x < SizeX; x++)
                {
                    IsUsed = Mn.Used.Not;
                    for (int ps = 0; ps < path.Length; ps++)
                    {
                        LibPF.Position p = path[ps];
                        if (p.X == x && p.Y == y)
                        {
                            IsUsed = (ps == 0 ? Mn.Used.Start : ((ps == (path.Length - 1)) ? Mn.Used.End : Mn.Used.Path));
                            break;
                        }
                    }
                    Sys.Console.Write(" ");
                    switch (IsUsed)
                    {
                    case Mn.Used.Not:
                        if (g.GetCellCost(x, y) == float.PositiveInfinity)
                        {
                            AUX = "xXx";
                            Sys.Console.ForegroundColor = Sys.ConsoleColor.Red;
                        }
                        else
                        {
                            AUX = "   ";
                            Sys.Console.ForegroundColor = stdColor;
                        }
                        break;

                    case Mn.Used.Start:
                        AUX = "-S-";
                        Sys.Console.ForegroundColor = Sys.ConsoleColor.Blue;
                        break;

                    case Mn.Used.Path:
                        AUX = "-U-";
                        Sys.Console.ForegroundColor = Sys.ConsoleColor.Green;
                        break;

                    case Mn.Used.End:
                        AUX = "-E-";
                        Sys.Console.ForegroundColor = Sys.ConsoleColor.Cyan;
                        break;
                    }
                    Sys.Console.Write(AUX);
                    Sys.Console.ForegroundColor = stdColor;
                    Sys.Console.Write(" |");
                }
                Sys.Console.Write(y.ToString());
                Sys.Console.WriteLine();
                Sys.Console.Write(" |");
                for (int x = 0; x < SizeX; x++)
                {
                    Sys.Console.Write("_____|");
                }
                Sys.Console.WriteLine();
            }
            posTime = Sys.DateTime.Now.Ticks;
            Sys.Console.WriteLine();
            Sys.Console.WriteLine();
            Sys.Console.WriteLine("Time (Draw Interface): " + Sys.TimeSpan.FromTicks(posTime - preTime).ToString());
        }
        else
        {
            Sys.Console.Write("Could Not Convert JSon | This is the first test to see if the Grid can be saved and loaded from files.");
        }
    }
コード例 #19
0
 public void SetCellCost(LibPF.Position position, float cost)
 {
     this.SetCellCost(position.X, position.Y, cost);
 }