Esempio n. 1
0
        private async Task <MazebotResult> PostSolution(MazebotResponse mazebotMaze, NavigationDetails solution)
        {
            MazebotResult result = null;

            if (solution.Arrived)
            {
                result = await _apiClient.SolveMazebotMaze(mazebotMaze.MazePath, solution.PathTaken);
            }
            return(result);
        }
        public async void Navigate_On_Swarm_Mode_Should_Return_The_First_Task_That_Completes_With_Arrived_True_Result()
        {
            var result1 = new NavigationDetails {
                Arrived = true, PathTaken = "result1"
            };
            var task1    = Task.Run(() => { Task.Delay(300); return(result1); });
            var crawler1 = Substitute.For <IMazeCrawler>();

            crawler1.Navigate().Returns(task1);

            var result2 = new NavigationDetails {
                Arrived = true, PathTaken = "result2"
            };
            var task2    = Task.Run(() => { Task.Delay(500); return(result2); });
            var crawler2 = Substitute.For <IMazeCrawler>();

            crawler2.Navigate().Returns(task2);

            var task3    = Task.Run(() => { Task.Delay(100); return(new NavigationDetails {
                    Arrived = false
                }); });
            var crawler3 = Substitute.For <IMazeCrawler>();

            crawler3.Navigate().Returns(task3);

            var crawlers = new [] { crawler1, crawler2, crawler3 };

            var swarmCoordinator = Substitute.For <ISwarmCoordinator>();

            swarmCoordinator.GetSwarm(Arg.Any <IMazeCrawlerState>()).Returns(crawlers);

            var crawlerCoordinator = Substitute.For <IMazeCrawlerCoordinator>();

            crawlerCoordinator.RequestSwarm(Arg.Any <IMazeCrawlerState>()).Returns(swarmCoordinator);

            var context = new MazeCrawlerContext
            {
                Start         = new Coordinates(0, 0),
                Destination   = new Coordinates(0, 1),
                NavigationMap = new Map(new char[][]
                {
                    new [] { Map.EMPTY, Map.EMPTY },
                    new [] { Map.EMPTY, Map.OCCPD }
                }),
                NavigationMode = CrawlerNavigationMode.Swarm,
                Coordinator    = crawlerCoordinator
            };
            var crawler = new MazeCrawler(context);

            var response = await crawler.Navigate();

            response.Should().BeEquivalentTo(result1);
        }
Esempio n. 3
0
#pragma warning disable CS1998,CS4014
        private async Task <NavigationDetails> SwarmNavigate()
        {
            var swarmCoordinator = _coordinator.RequestSwarm(this);
            var swarm            = swarmCoordinator.GetSwarm(this);

            Trace($"Received {swarm.Count()} crawler(s) from the swarm.");

            NavigationDetails result = null;
            var tasks             = new Dictionary <int, Task>();
            var cancelationSource = new CancellationTokenSource();

            foreach (var crawler in swarm)
            {
                // Add the Navigate task of each MazeCrawler to a list and remove it once it completes.
                Trace($"Crawler {crawler.Id} to continue with the navigation.");
                var task = Task.Run(() => crawler.Navigate(), cancelationSource.Token);

                tasks.Add(task.Id, task);
                task.ContinueWith(completed =>
                {
                    lock (tasks)
                    {
                        Trace($"Swarm with task#{completed.Id} completed its navigation.");

                        if (completed.IsCompletedSuccessfully && completed.Result.Arrived)
                        {
                            // Cancel the other Navigate tasks from the list since the destination Coordinates has been reached already.
                            result = completed.Result;
                            Trace($"Crawler with task#{completed.Id} arrived. Reporting arrival.");
                            cancelationSource.Cancel();
                        }

                        tasks.Remove(completed.Id);
                        Trace($"Swarm has {tasks.Count()} task(s) left.");
                    }
                });

                while (tasks.Count() > 0)
                {
                    await Task.Delay(25);
                }
                ;
            }

            cancelationSource.Dispose();

            return(result ?? new NavigationDetails {
                Arrived = false
            });
        }
        public async void Navigate_Should_Call_Spawned_IMazeCrawler_Navigate()
        {
            _queen.ScanMap(new Coordinates(1, 2), new Coordinates(3, 4), new Map(new char[0][]));

            var expected = new NavigationDetails();
            var crawler  = Substitute.For <IMazeCrawler>();

            crawler.Navigate().Returns(expected);
            _spawner.Spawn(Arg.Any <MazeCrawlerContext>()).Returns(crawler);

            var response = await _queen.Navigate();

            await crawler.Received(1).Navigate();

            response.Should().Be(expected);
        }
Esempio n. 5
0
        public async Task <NavigationDetails> Navigate()
        {
            Trace($"Starting navigation preference: {string.Join(',', _preference )}.");

            NavigationDetails response = null;

            switch (NavigationMode)
            {
            case CrawlerNavigationMode.Scout:
                // Scout will force the MazeCrawler to traverse by itself the map starting from its current Coordinates until it reaches the destination Coordinates (or a deadend is reached).
                response = Scout();
                break;

            case CrawlerNavigationMode.Swarm:
                // Swarm will make the MazeCrawler to traverse the map by itself until it reaches a path that forks.
                // When this happens, the MazeCrawler will request for other MazeCrawlers and will force each of them to traverse the succeeding path (one for each fork on the path).
                response = await Swarm();

                break;
            }

            return(response);
        }