Ejemplo n.º 1
0
        public RobotOutputResult MoveRobotToPoint(string targetPoint)
        {
            if (!IsAutomated)
            {
                throw new Exception("This should only be done in automated mode");
            }

            RobotOutputResult result = null;

            // Initialize the movement variables
            var path = GetPathToPoint(RobotPosition, targetPoint);

            if (path.Path.Count == 0)
            {
                throw new Exception("Path not found");
            }
            var    movementCommands  = GetMovementCommandsForPath(path.Path);
            string nextRobotPosition = RobotPosition;

            // Continue looping until the robot reaches the target
            while (!RobotPosition.Equals(targetPoint))
            {
                // Run a loop of the program
                _programStatus = _computer.RunProgram();

                // Process program output
                // Assumption: If there is new output, then the robot has
                // entered a room corresponding to the next robot position
                if (_outputIndex < _outputListener.Values.Count)
                {
                    int numberOfNewOutputValues = _outputListener.Values.Count - _outputIndex;
                    var latestOutput            = string.Join("", _outputListener.Values
                                                              .GetRange(_outputIndex, numberOfNewOutputValues)
                                                              .Select(v => char.ConvertFromUtf32((int)v)));
                    _outputIndex += numberOfNewOutputValues;

                    var robotOutputResult = RobotOutputHelper.ProcessRobotOutput(latestOutput);
                    if (!RobotOutputType.MovedToPoint.Equals(robotOutputResult.Type) &&
                        !RobotOutputType.EjectedBack.Equals(robotOutputResult.Type) &&
                        IsAutomated)
                    {
                        throw new Exception("While exploring in automated mode, we should only either move into spaces or get ejected back by the security system");
                    }

                    // Update the set of explored points
                    if (robotOutputResult.ShipSectionInfo != null)
                    {
                        if (!ExploredPoints.ContainsKey(nextRobotPosition))
                        {
                            ExploredPoints.Add(nextRobotPosition, robotOutputResult.ShipSectionInfo);
                        }
                        ExploredPoints[nextRobotPosition] = robotOutputResult.ShipSectionInfo;

                        // Remove this point from the set of unxplored points
                        if (UnexploredPoints.Contains(nextRobotPosition))
                        {
                            UnexploredPoints.Remove(nextRobotPosition);
                        }
                    }

                    // Only move the robot if they actually moved
                    if (RobotOutputType.MovedToPoint.Equals(robotOutputResult.Type))
                    {
                        RobotPosition = nextRobotPosition;
                    }
                    else if (RobotOutputType.EjectedBack.Equals(robotOutputResult.Type))
                    {
                        RallyPoint = RobotPosition;
                        result     = robotOutputResult;
                        break;
                    }

                    if (RobotPosition.Equals(targetPoint))
                    {
                        result = robotOutputResult;
                        break;
                    }
                }

                // Provide input for the program
                if (IntcodeProgramStatus.AwaitingInput.Equals(_programStatus))
                {
                    if (movementCommands.Count == 0 &&
                        !RobotPosition.Equals(targetPoint))
                    {
                        throw new Exception("Ran out of commands before robot reached target");
                    }

                    string movementCommand = movementCommands.Dequeue();
                    _inputProviderAutomated.AddInputValue(movementCommand);
                    _inputProviderAutomated.AddInputValue(10);
                    nextRobotPosition = RobotMovementHelper.Move(RobotPosition, movementCommand);
                }

                _programLoopCount++;
            }
            return(result);
        }