#include #include #define MIN_COORD 0 #define MAX_COORD 7 struct Robot { /* boundaries */ int ymax; int ymin; int xmax; int xmin; int curr_x; int curr_y; int prev_read; int dir; /* N = 0, E = 1, S = 2, W = 3 */ int number_moves; int moves_n; int moves_s; int moves_w; int moves_e; int wrong_dir; int wrong_moves; } ; int UpdatePosition(Robot * R); Robot * InitRobot() { Robot * R = new Robot; R->ymax = MAX_COORD ; R->ymin = MIN_COORD ; R->xmax = MAX_COORD ; R->xmin = MIN_COORD ; R->curr_x = MAX_COORD/2 ; R->curr_y = MAX_COORD/2 ; R->prev_read = 0; R->dir = 0; R->wrong_dir = 0; R->number_moves = 0; R->moves_n = 0; R->moves_s = 0; R->moves_w = 0; R->moves_e = 0; R->wrong_moves = 0; return R; } int ReadSensor(int xcoord, int ycoord, Robot * R) { int sensor; int imax = MAX_COORD; int xd = abs(R->curr_x - xcoord); int yd = abs(R->curr_y - ycoord); int dmax; if (xd >= yd) { dmax = xd; } else { dmax = yd; } sensor = imax - dmax; return sensor; } void Move(Robot * R) { R->number_moves++; switch (R->dir) { case 0: { cout << "Moving north from " << "(" << R->curr_x << "," << R->curr_y << ")\n" ; R->moves_n++; R->curr_y++; } break; case 1: { cout << "Moving east from " << "(" << R->curr_x << "," << R->curr_y << ")\n" ; R->moves_e++; R->curr_x++; } break; case 2: { cout << "Moving south from " << "(" << R->curr_x << "," << R->curr_y << ")\n" ; R->moves_s++; R->curr_y--; } break; case 3: { cout << "Moving west from " << "(" << R->curr_x << "," << R->curr_y << ")\n" ; R->moves_w++; R->curr_x--; } break; } return; } int InBounds(Robot * R) { int check_step = 0; switch (R->dir) { case 0 : { // check_step = R->curr_y+1; // if (check_step > MAX_COORD || check_step < MIN_COORD || // check_step >= R->ymax) { // return 0; // } // else { // return 1; // } if (R->curr_y == MAX_COORD || R->curr_y == R->ymax) { return 0; } else { return 1; } } break; case 1: { // check_step = R->curr_x+1; // if (check_step > MAX_COORD || check_step < MIN_COORD || // check_step >= R->xmax) { // return 0; // } // else { // return 1; // } if (R->curr_x == MAX_COORD || R->curr_x == R->xmax) { return 0; } else { return 1; } } break; case 2: { // check_step = R->curr_y-1; // if (check_step > MAX_COORD || check_step < MIN_COORD || // check_step <= R->ymin) { // return 0; // } // else { // return 1; // } if (R->curr_y == MIN_COORD || R->curr_y == R->ymin) { return 0; } else { return 1; } } break; case 3: { // check_step = R->curr_x-1; // if (check_step > MAX_COORD || check_step < MIN_COORD || // check_step <= R->xmin) { // return 0; // } // else { // return 1; // } if (R->curr_x == MIN_COORD || R->curr_x == R->xmin) { return 0; } else { return 1; } } break; default : { cout << "Undefined direction case!\n"; exit(1); } } } int UpdatePosition(Robot * R) { int initial_dir = R->dir; if (R->wrong_dir) { cout << "Wrong direction -- recovering.\n"; Move(R); R->wrong_dir = 0; } if (R->xmax == R->xmin && R->ymax == R->ymin) { cout << "Boundares equal. X = " << R->xmax << " Y = " << R->ymax << endl; return 0; } if (InBounds(R)) { Move(R); } else { R->dir = ((R->dir)+1) % 4; // while (!InBounds(R) && (initial_dir != R->dir)) { while (!InBounds(R)) { R->dir = ((R->dir)+1) % 4; } // if (initial_dir == R->dir) { // return 0; // } Move(R); } return 1; } void SeekTarget(Robot * R, int xcoord, int ycoord) { int cont = 1; int new_read; new_read = ReadSensor(xcoord, ycoord, R); cont = UpdatePosition(R); while (cont) { R->prev_read = new_read; new_read = ReadSensor(xcoord, ycoord, R); cout << "New sensor reading is: " << new_read << endl; if (new_read > R->prev_read) { switch (R->dir) { case 0 : { // R->ymin = R->curr_y - 1; R->ymin = R->curr_y; } break; case 1 : { // R->xmin = R->curr_x - 1; R->xmin = R->curr_x; } break; case 2 : { // R->ymax = R->curr_y + 1; R->ymax = R->curr_y ; } break; case 3 : { // R->xmax = R->curr_x + 1; R->xmax = R->curr_x ; } break; default : { cout << "Error -- out of bounds direction " << R->dir << endl; exit(1); } } } else if (new_read < R->prev_read) { cout << "New read: " << new_read << " Prev read: " << R->prev_read << endl; R->wrong_moves++; R->wrong_dir = 1; new_read = R->prev_read; switch (R->dir) { case 0 : { R->dir = 2; R->ymax = R->curr_y-1; } break; case 1 : { R->dir = 3; R->xmax = R->curr_x-1; } break; case 2 : { R->dir = 0; R->ymin = R->curr_y+1; } break; case 3 : { R->dir = 1; R->xmin = R->curr_x+1; } break; default : { cout << "Error -- out of bounds direction " << R->dir << endl; exit(1); } } } else /* new == old */ { switch (R->dir) { case 0 : R->dir = 1; break; case 1 : R->dir = 2; break; case 2 : R->dir = 3; break; case 3 : R->dir = 0; break; default : cout << "Error -- out of bounds direction " << R->dir << endl; exit(1); } } cont = UpdatePosition(R); } return ; } void PrintResults(Robot * R) { cout << "Position (" << R->curr_x << "," << R->curr_y << ")\n"; cout << "Total moves: " << R->number_moves << endl; cout << "Moves north: " << R->moves_n << endl; cout << "Moves south: " << R->moves_s << endl; cout << "Moves east: " << R->moves_e << endl; cout << "Moves west: " << R->moves_w << endl; cout << "Wrong moves: " << R->wrong_moves << endl; return; } int main ( int argc, char ** argv ) { unsigned int xcoord, ycoord; Robot * R; if (argc < 3) { cout << "Usage: robot \n"; exit(1); } xcoord = atoi(argv[1]); ycoord = atoi(argv[2]); if (xcoord > MAX_COORD || xcoord < MIN_COORD || ycoord > MAX_COORD || xcoord < MIN_COORD) { cout << "Invalid target coordinate value\n"; exit(1); } R = InitRobot(); SeekTarget(R, xcoord, ycoord); PrintResults(R); }