I have this function that returns the location of a robot (which is just a [row][col] pair of indices from a matrix):
std::pair<int, int> World::getRobotLocation(char robot_name){
auto const & location = robots.find(robot_name);
if (location == robots.end()) {
std::cout << "Robot " << robot_name << " does not exist." << std::endl;
}
return location->second;
}
Below, I am trying to implement the move() function, which takes in the robot name, location and which direction to move and updates the position accordingly:
std::string move(char robot, char direction) {
// Get robot and its location
std::pair<int, int> robot_location = std::pair<int, int> World::getRobotLocation(robot);
// Get direction to move from user
// if L, map_[row 1][col]
// if D, map_[row][col 1]
// if R, map_[row-1][col]
// if U, map_[row][col 1]
// According to user input, update the robot's location
if (direction == 'L') {
robot_location = robot_location[ 1][]
}
else if (direction == 'D') {
robot_location = robot_location[][-1]
}
else if (direction == 'R') {
robot_location = robot_location[-1][]
}
else {
robot_location = robot_location[][ 1]
}
}
In my variable robot_location, I am saving the location of that particular robot. How can I access the values of this std::pair<int, int> to be able to update them?
CodePudding user response:
I think you want something like this:
if (direction == 'L') {
robot_location.first = 1;
}
else if (direction == 'D') {
robot_location.second -= 1;
}
// ...etc (you get the idea)
first and second are the names of the two elements in a std::pair (that's also why the return value of robots.find(...) dereferences to something that has first and second - that's a std::pair of the key and value types of the map).
Bear in mind that getRobotLocation, as it's currently written, will return a copy of the std::pair of coordinates, not a reference to the original coordinates inside the map. Therefore, just updating that std::pair won't be enough on its own. You'll need to either save the value back into the robots map, or change what getRobotLocation returns (see @Goswin and @Ted's comments).
CodePudding user response:
Your first function has a bug. It reports when a robot is not found, but still dereferences the end iterator, which causes undefined behavior. Instead, you should return a pointer, which is conditionally null:
// Returns null if the robot is not found:
std::pair<int, int>*
World::getRobotLocation(char robot_name){
auto const location = robots.find(robot_name);
if (location == robots.end()) {
return nullptr;
}
return &location->second;
}
And in your other function, you check to see, if the pointer is not null, you update the value:
// Returns true if move happens,
// false otherwise.
bool
move(char robot, char direction) {
auto const robot_location = World::getRobotLocation(robot);
if (!robot_location) return false;
switch (direction) {
case 'L': {
robot_location->first;
} break;
case 'D': {
--robot_location->second;
} break;
case 'R': {
--robot_location->first;
} break;
default: {
robot_location->second;
} break;
}
return true;
}
