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