示例#1
0
        private IEnumerable <IAction> GetPossibleActions(CaveSearch caveSearch, Cave cave)
        {
            if (cave.TargetLocation == caveSearch.Location)
            {
                return(new ChangeEquipment(Torch.Value).RepeatOnce());
            }

            return(MoveDirections
                   .Select(d => (destination: caveSearch.Location + d, direction: d))
                   .Where(m => m.destination.X >= 0 && m.destination.Y >= 0)
                   .Select(m =>
            {
                var regionAtDestination = cave[m.destination];
                var regionAtCurrent = cave[caveSearch.Location];

                if (caveSearch.Equipment.CanEnter(regionAtDestination))
                {
                    return new MoveInDirection(m.direction) as IAction;
                }

                return Equipments
                .Where(e => CanEnterRegionsWithEquipment(e, regionAtCurrent, regionAtDestination))
                .Select(e => new ChangeEquipment(e))
                .First();
            }));
        }
示例#2
0
        public CaveSearch FindQuickestPath(Cave cave)
        {
            var targetSearch         = new CaveSearch(cave.TargetLocation, Torch.Value);
            var initialSearch        = new CaveSearch(cave.InitialLocation, Torch.Value);
            var caveSearchesToExpand = initialSearch.RepeatOnce().ToHashSet(SearchEqualityComparerByEquipmentAndLocation.Value);
            var reachedSearches      = initialSearch.RepeatOnce().ToHashSet(SearchEqualityComparerByEquipmentAndLocation.Value);
            var searchComparer       = new CaveSearchComparerByCostAndRemainignPathLength(cave.TargetLocation);

            CaveSearch currentSearchToTarget = null;

            do
            {
                // TODO use sorted data structure
                var searchToExpand = caveSearchesToExpand.MinBy(searchComparer);

                var expandedSearches = ExpandCaveSearch(searchToExpand, cave)
                                       .Where(s => !reachedSearches.TryGetValue(s, out var other) || s.Cost < other.Cost);

                caveSearchesToExpand.Remove(searchToExpand);

                foreach (var expandedSearch in expandedSearches)
                {
                    caveSearchesToExpand.AddOrUpdate(expandedSearch, (@new, old) => @new.Cost < old.Cost);
                    reachedSearches.AddOrUpdate(expandedSearch, (@new, old) => @new.Cost < old.Cost);
                }

                reachedSearches.TryGetValue(targetSearch, out currentSearchToTarget);
            } while (currentSearchToTarget == null);

            return(currentSearchToTarget);
        }
示例#3
0
 private IEnumerable <CaveSearch> ExpandCaveSearch(CaveSearch caveSearchToExpand, Cave cave)
 {
     return(GetPossibleActions(caveSearchToExpand, cave)
            .Select(a => a.ApplyAction(caveSearchToExpand)));
 }