예제 #1
0
        private static void CreatePath(State state, Point start, List <Point> notVisitedTargets,
                                       PathWithCost resultPath, PathWithTarget bestPath)
        {
            CorrectBestPath(bestPath, resultPath, notVisitedTargets);

            var pathFinder = new DijkstraPathFinder();
            var paths      = pathFinder.GetPathsByDijkstra(state, start, notVisitedTargets);

            foreach (var path in paths)
            {
                var cost = resultPath.Cost + path.Cost;
                if (cost <= state.Energy)
                {
                    notVisitedTargets.Remove(path.End);

                    var way = resultPath.Path.ToList();
                    way.AddRange(path.Path.Skip(1));
                    CreatePath(state, path.End, notVisitedTargets,
                               new PathWithCost(cost, way.ToArray()), bestPath);

                    if (bestPath.NumberOfTargets == 0)
                    {
                        return;
                    }

                    notVisitedTargets.Add(path.End);
                }
            }
        }
예제 #2
0
 private static void CorrectBestPath(PathWithTarget bestPath, PathWithCost resultPath,
                                     List <Point> notVisitedTargets)
 {
     if (bestPath.NumberOfTargets > notVisitedTargets.Count)
     {
         bestPath.Path            = resultPath.Path.ToList();
         bestPath.NumberOfTargets = notVisitedTargets.Count;
     }
 }
예제 #3
0
        public List <Point> FindPathToCompleteGoal(State state)
        {
            var notVisitedChests = state.Chests.ToList();
            var start            = state.Position;
            var resultPath       = new PathWithCost(0, start);
            var bestPath         = new PathWithTarget(new List <Point>(), state.Chests.Count);

            CreatePath(state, start, notVisitedChests, resultPath, bestPath);
            return(bestPath.Path.Skip(1).ToList());
        }
예제 #4
0
        private PathWithCost GetPath(Point end, Dictionary <Point, DijkstraData> track)
        {
            var result = new PathWithCost(track[end].Price, end);

            end = track[end].Previous;
            while (end != new Point(-1, -1))
            {
                result.Path.Add(end);
                end = track[end].Previous;
            }
            result.Path.Reverse();
            return(result);
        }
예제 #5
0
        private static PathWithCost TakePath(IReadOnlyDictionary <Point, Point?> paths, Point endP, int cost)
        {
            var   path  = new PathWithCost(cost);
            Point?point = endP;

            while (point != null)
            {
                path.Path.Add((Point)point);
                point = paths[(Point)point];
            }

            path.Path.Reverse();
            return(path);
        }
예제 #6
0
        public PathWithCost MakePath(Dictionary <Point, DijkstraData> track, Point end)
        {
            var   result       = new List <Point>();
            Point?currentPoint = end;

            while (currentPoint != null)
            {
                result.Add(currentPoint.Value);
                currentPoint = track[currentPoint.Value].Previous;
            }
            result.Reverse();
            PathWithCost pathResult = new PathWithCost(track[end].Price, result.ToArray());

            return(pathResult);
        }
예제 #7
0
        private void ProceedNeighbours(State state, Dictionary <Point, PathWithCost> track, Point toOpen, int bestPrice)
        {
            var possibleMoves = moves.Select(x => toOpen + x).Where(x => state.InsideMap(x) && !state.IsWallAt(x));

            foreach (var nextPoint in possibleMoves)
            {
                var currentPrice = track[toOpen].Cost + state.CellCost[nextPoint.X, nextPoint.Y];
                var path         = new List <Point>(track[toOpen].Path)
                {
                    nextPoint
                };
                if (!track.ContainsKey(nextPoint) || currentPrice < bestPrice)
                {
                    track[nextPoint] = new PathWithCost(currentPrice, path.ToArray());
                }
            }
        }
예제 #8
0
        public List <Point> FindPathToCompleteGoal(State state)
        {
            if (state.Goal == 0)
            {
                return(new List <Point>());
            }

            HashSet <Point>    chests = new HashSet <Point>(state.Chests);
            DijkstraPathFinder finder = new DijkstraPathFinder();
            List <Point>       result = new List <Point>();

            var currentCost = 0;
            var position    = state.Position;

            for (int i = 0; i < state.Goal; i++)
            {
                if (!chests.Any())
                {
                    return(new List <Point>());
                }
                PathWithCost pathToNewChest = finder.GetPathsByDijkstra(state, position, chests).FirstOrDefault();
                if (pathToNewChest == null)
                {
                    return(new List <Point>());
                }
                position     = pathToNewChest.End;
                currentCost += pathToNewChest.Cost;
                if (currentCost > state.Energy)
                {
                    return(new List <Point>());
                }
                chests.Remove(pathToNewChest.End);

                for (int j = 1; j < pathToNewChest.Path.Count; j++)
                {
                    result.Add(pathToNewChest.Path[j]);
                }
            }

            return(result);
        }