Exemple #1
0
            public Ship(Func <ISet <IZoneInfo> > getZoneInfosFunc, IZoneInfo currentPosition, int speedInMilliseconds, int maxDistance)
                : base(getZoneInfosFunc, currentPosition)
            {
                SpeedInMilliseconds = speedInMilliseconds;
                _pathEnumeratorTask = new Task <IEnumerator <ShipPathNode> >(() =>
                {
                    var pathNode = new ShipPathNode(CurrentPosition, maxDistance);

                    var enumerator = pathNode
                                     .EnumerateAllChildPathNodes()
                                     .Where(x => x.Distance < maxDistance)
                                     .GroupBy(x => CalculateDistance(CurrentPosition.Point, x.CurrentZoneInfo.Point))
                                     .OrderByDescending(x => x.Key)
                                     .FirstOrDefault()
                                     ?.OrderBy(x => x.Distance)
                                     ?.FirstOrDefault()
                                     ?.EnumeratePathBackwards()
                                     ?.GetEnumerator() ?? new List <ShipPathNode>()
                    {
                        pathNode
                    }.GetEnumerator();

                    enumerator.MoveNext();

                    return(enumerator);
                });
                _pathEnumeratorTask.Start();
            }
Exemple #2
0
                private ShipPathNode(
                    IZoneInfo rootZoneInfo,
                    IZoneInfo currentZoneInfo,
                    ShipPathNode preceedingShipPathNode,
                    ISet <IZoneInfo> seenPaths,
                    int distance,
                    int maxDistance
                    )
                {
                    _maxDistance = maxDistance;
                    if (rootZoneInfo == null)
                    {
                        throw new ArgumentNullException(nameof(rootZoneInfo));
                    }
                    _rootZoneInfo = rootZoneInfo;
                    if (currentZoneInfo == null)
                    {
                        throw new ArgumentNullException(nameof(currentZoneInfo));
                    }
                    CurrentZoneInfo = currentZoneInfo;

                    if (!seenPaths.Add(currentZoneInfo))
                    {
                        throw new ArgumentException("'currentZoneInfo' was already added to this path.", nameof(currentZoneInfo));
                    }

                    _preceedingShipPathNode = preceedingShipPathNode;

                    Distance      = distance;
                    _childrenLazy = new Lazy <IEnumerable <ShipPathNode> >(() => CurrentZoneInfo
                                                                           .GetNorthEastSouthWest()
                                                                           .Where(x => Distance + 1 < maxDistance)
                                                                           .Where(x => x.HasMatch)
                                                                           .Where(x => _preceedingShipPathNode != null ? x.MatchingObject != _preceedingShipPathNode.CurrentZoneInfo : true)
                                                                           .Where(x => !seenPaths.Contains(x.MatchingObject))
                                                                           .Where(x => IsSuitableForShip(x.MatchingObject))
                                                                           .OrderByDescending(x => CalculateDistance(x.MatchingObject.Point, _rootZoneInfo.Point))
                                                                           .Where(x => !seenPaths.Contains(x.MatchingObject))
                                                                           .Select(x =>
                                                                                   new ShipPathNode(
                                                                                       rootZoneInfo: rootZoneInfo,
                                                                                       currentZoneInfo: x.MatchingObject,
                                                                                       preceedingShipPathNode: this,
                                                                                       seenPaths: seenPaths,
                                                                                       distance: Distance + 1,
                                                                                       maxDistance: _maxDistance
                                                                                       )
                                                                                   )
                                                                           );
                }