示例#1
0
        public IList <string> GetNeighbors(string point)
        {
            var result = new List <string>();

            if (!ExploredPoints.ContainsKey(point))
            {
                return(result);
            }
            foreach (var directionString in ExploredPoints[point].Directions)
            {
                var neighbor = RobotMovementHelper.Move(point, directionString);
                result.Add(neighbor);
            }
            return(result);
        }
示例#2
0
        public IList <string> GetNewUnexploredPoints()
        {
            if (!ExploredPoints.ContainsKey(RobotPosition))
            {
                throw new Exception("Robot position not explored");
            }
            IList <string> result = new List <string>();

            foreach (var directionString in ExploredPoints[RobotPosition].Directions)
            {
                var nextPoint = RobotMovementHelper.Move(RobotPosition, directionString);
                if (!ExploredPoints.ContainsKey(nextPoint) &&
                    !ExplorationTree.Contains(nextPoint))
                {
                    result.Add(nextPoint);
                }
            }
            return(result);
        }
示例#3
0
        public void Explore()
        {
            // Initialize the exploration variables
            string targetUnexploredPoint = RobotPosition;
            var    movementCommandsToTargetUnexploredPoint = new Queue <string>();
            string nextRobotPosition = RobotPosition;

            // Continue exploring while points remain unexplored
            while (ExplorationTree.Count > 0)
            {
                // 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;
                    if (!IsAutomated)
                    {
                        Console.WriteLine(latestOutput);
                    }

                    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");
                    }

                    // Add this point to 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);
                        }
                    }

                    // Reset the target unexplored point if we've reached it
                    if (nextRobotPosition.Equals(targetUnexploredPoint))
                    {
                        targetUnexploredPoint = null;
                    }

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

                    // Add any new unexplored points
                    var newUnexploredPoints = GetNewUnexploredPoints();
                    ExplorationTree.Add(newUnexploredPoints, RobotPosition);
                    foreach (var p in newUnexploredPoints)
                    {
                        UnexploredPoints.Add(p);
                    }
                }

                // Provide input for the program
                if (IntcodeProgramStatus.AwaitingInput.Equals(_programStatus))
                {
                    if (!IsAutomated)
                    {
                        DrawMap();
                        var userInput = _inputProviderManual.AddInput(appendNewLine: true).Trim();
                        var isValidMovementCommand = RobotMovementHelper.GetIsValidMovementCommand(userInput);
                        if (isValidMovementCommand)
                        {
                            nextRobotPosition = RobotMovementHelper.Move(RobotPosition, userInput);
                        }
                        targetUnexploredPoint = GetNextTargetUnexploredPoint(
                            currentTargetUnexploredPoint: RobotPosition);
                    }
                    else
                    {
                        if (targetUnexploredPoint != null &&
                            movementCommandsToTargetUnexploredPoint.Count == 0)
                        {
                            throw new Exception("Ran out of movement commands before reaching target");
                        }

                        // Acquire a new target unexplored point if necessary
                        // If the target unexplored point is null, then the
                        // robot reached the previous target
                        // If the next target unexplored point is null, then
                        // we've finished exploring
                        if (targetUnexploredPoint == null)
                        {
                            targetUnexploredPoint = GetNextTargetUnexploredPoint(
                                currentTargetUnexploredPoint: RobotPosition);
                            if (targetUnexploredPoint != null)
                            {
                                var pathToTarget = GetPathToPoint(
                                    startPoint: RobotPosition,
                                    targetPoint: targetUnexploredPoint);
                                if (pathToTarget.Path.Count == 0)
                                {
                                    throw new Exception("Path not found");
                                }
                                movementCommandsToTargetUnexploredPoint = GetMovementCommandsForPath(
                                    path: pathToTarget.Path);
                            }
                        }

                        // If the target is null, then we finished exploring
                        // Otherwise, input the new movement command
                        // and update the next robot position
                        if (targetUnexploredPoint != null)
                        {
                            if (movementCommandsToTargetUnexploredPoint.Count == 0)
                            {
                                throw new Exception("Failed to properly acquire new target path");
                            }

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

                _programLoopCount++;
            }

            // Exploration complete, populate item lists
            InitializeItemTrackers();
        }
示例#4
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);
        }