private static async Task <List <LocationDTO> > ApplyAStarAlgorithm()
        {
            var       finalCitiesList = new List <LocationDTO>();
            AStarCity currentCity     = null;
            var       originCity      = GetOriginCity();

            if (originCity != null)
            {
                originCity.Visited = true;
                Cities.FirstOrDefault(x => x.City.Id == originCity.City.Id).Visited = true;
                finalCitiesList.Add(GetLocation(originCity));
                currentCity = originCity;
            }
            else
            {
                finalCitiesList = null;
                return(null);
            }

            while (AreNotVisitedCities())
            {
                var unvisitedCities       = GetUnvisitedIntermediateCities();
                var scoredUnvisitedCities = await GetScores(currentCity, unvisitedCities);

                if (scoredUnvisitedCities.Any(x => x.Score == 0) && _timeImportanceCoeficient < 99)
                {
                    ResetAlgorithm();
                    finalCitiesList.Clear();
                    finalCitiesList.Add(GetLocation(originCity));
                    _timeImportanceCoeficient++;
                }
                else
                if (!scoredUnvisitedCities.Any(x => x.Score == 0))
                {
                    var highestScoredCity = GetHighestScoredCity(scoredUnvisitedCities);
                    //set highestScoredCity to visited
                    Cities.FirstOrDefault(x => x.City.Id == highestScoredCity.City.City.Id).Visited = true;
                    finalCitiesList.Add(GetLocation(highestScoredCity.City));
                    currentCity = highestScoredCity.City;
                }
                else
                {
                    NoRouteFound = true;
                    return(null);
                }
            }

            var destinationCity = GetDestinationCity();

            if (destinationCity != null)
            {
                finalCitiesList.Add(GetLocation(destinationCity));
            }
            else
            {
                finalCitiesList = null;
            }
            return(finalCitiesList);
        }
        private static async Task <List <ScoredAStarCity> > GetScores(AStarCity start, List <AStarCity> neighbors)
        {
            List <ScoredAStarCity> highScores = new List <ScoredAStarCity>();

            foreach (var neighbor in neighbors)
            {
                double score = await CalculateScore(start, neighbor);

                highScores.Add(new ScoredAStarCity {
                    Score = score, City = neighbor
                });
            }
            return(highScores);
        }
 private static LocationDTO GetLocation(AStarCity city)
 {
     if (city.City.NeedsMuseum)
     {
         return(city.City.SelectedMuseum.geometry.location);
     }
     else
     if (city.City.NeedsRestaurant)
     {
         return(city.City.SelectedRestaurant.geometry.location);
     }
     else
     {
         return(city.City.Location);
     }
 }
        private static async Task <double> CalculateScore(AStarCity start, AStarCity end)
        {
            var startLocation = GetLocation(start);
            var endLocation   = GetLocation(end);

            await GetTravelInfo(startLocation, endLocation);

            while (Result == null)
            {
                await Task.Delay(25);
            }
            double distanceScore = 1 / (double)Result.distance.value;

            CurrentTime = CurrentTime.AddSeconds(Result.duration.value);
            if (CurrentTime > end.City.ArrivingTime)
            {
                return(0);
            }
            double timeScore = (1 /
                                (end.City.ArrivingTime.Subtract(CurrentTime).TotalSeconds)) * _timeImportanceCoeficient;

            Result = null;
            return(distanceScore + timeScore);
        }