/** * robot3.cpp * * created: 4-nov-07/sklar (based on robot2.cpp) * * a sample simulation environment in which a robot looks for dirt to vacuum. * the robots' world contains dirt and one robot. the robot moves around * randomly until it finds some dirt and vacuums it. * * differences from robot2.cpp: demonstrates function overriding by * introduction of the "creature" class and different versions for * subclasses "robot" and "cat" * */ #include #include #include using namespace std; enum direction {north, east, south, west}; const int WORLD_SIZE = 5; const int MAX_SPOTS = 3; /*---------------------------------------------------------------------------*/ /** * point class * * this class should look familiar by now: it has a 2-D (x,y) coordinate * and functions that support setting, reporting and printing it. * */ class point { private: int x, y; public: int getX() const; int getY() const; void set( int x, int y ); void print() const; }; int point::getX() const { return x; } int point::getY() const { return y; } void point::set( int x, int y ) { this->x = x; this->y = y; } void point::print() const { cout << "(" << x << ", " << y << ") "; } /*---------------------------------------------------------------------------*/ /** * dirt class * * dirt is a kind of point that reacts when it is vacuumed * */ class dirt : public point { private: bool gone; public: dirt() { gone = false; } void disappear(); }; void dirt::disappear(){ cout << "poof!" << endl; gone = true; } /*---------------------------------------------------------------------------*/ /** * creature class * * a creature is a kind of point that moves around * */ class creature : public point { public: void move(); void move( direction d ); }; // pick a random direction to move in, and then move one unit in that direction void creature::move(){ direction d; d = static_cast( rand() % 4 ); move( d ); } // move in a specific direction, wrapping around if necessary. // the overloaded function move provides this abilty. void creature::move( direction d ){ int x = getX(); int y = getY(); // find a new x and y coordinate switch( d ) { case north: y = (y + 1) % WORLD_SIZE; break; case south: y = (y - 1); if ( y < 0 ) { y = WORLD_SIZE; } break; case east: x = (x + 1) % WORLD_SIZE; break; case west: x = (x - 1) % WORLD_SIZE; if ( x < 0 ) { x = WORLD_SIZE; } break; } // set the location of the creature to those coordinates set( x, y ); } /*---------------------------------------------------------------------------*/ /** * robot class * * a robot is a kind of creature that vacuums up dirt spots * */ class robot : public creature { private: int num_vacuumed; public: robot() { num_vacuumed = 0; } void vacuum(); bool busy( int num_spots ); }; // vacuum up some dirt void robot::vacuum(){ cout << "shrooooop..."; num_vacuumed++; } // the robot is busy until all the dirt has been found and vacuumed bool robot::busy( int num_spots ) { if ( num_vacuumed < num_spots ){ return true; } else { return false; } } /*---------------------------------------------------------------------------*/ /** * cat class * * a cat is a kind of creature * */ class cat : public creature { public: void move(); void move( direction d ); }; void cat::move(){ direction d; d = static_cast(rand() % 4); move(d); } // overload the creature's move so cat can pounce (move 2 steps in any direction) void cat::move( direction d ){ int x = getX(); int y = getY(); // find a new x and y coordinate switch( d ) { case north: y = (y + 2) % WORLD_SIZE; break; case south: y = (y - 2); if ( y < 0 ) { y = WORLD_SIZE; } break; case east: x = (x + 2) % WORLD_SIZE; break; case west: x = (x - 2) % WORLD_SIZE; if ( x < 0 ) { x = WORLD_SIZE; } break; } // set the location of the cat to those coordinates set( x, y ); } /*---------------------------------------------------------------------------*/ /** * world class * */ class world { private: robot rosie; dirt spots[MAX_SPOTS]; int num_spots; cat felix; public: world() { num_spots = 0; } void setRobot( int x, int y ); void setCat( int x, int y ); void setSpot( int x, int y ); int findSpot( int x, int y ) const; void robotRoam(); void print() const; }; void world::setRobot( int x, int y ) { rosie.set( x, y ); } void world::setCat( int x, int y ) { felix.set( x, y ); } void world::setSpot( int x, int y ) { if ( num_spots+1 < MAX_SPOTS ) { spots[num_spots++].set( x, y); } } int world::findSpot( int x, int y ) const{ bool found = false; int index = 0; while (( ! found ) && ( index < num_spots )) { if (( x == spots[index].getX() ) && ( y == spots[index].getY() )){ found = true; } index++; } if ( found ) { return( index ); } else { return( -1 ); } } // end of findSpot() // make the robot roam around. if it finds a spot, it vacuums it up. // it does this as long as it is "busy", i.e., as long as there are spots // in the world that need to be cleaned. void world::robotRoam() { int index; felix.move(); setSpot( felix.getX(), felix.getY() ); while ( rosie.busy( num_spots ) ) { rosie.move(); rosie.print(); if (( index = findSpot( rosie.getX(), rosie.getY() )) > 0 ) { rosie.vacuum(); spots[index].disappear(); } felix.move(); setSpot( felix.getX(), felix.getY() ); } } // end of robotRoam() // printing the world is printing the location of the objects in the // world. we use their print methods to do this. void world::print() const { cout << "\nRosie is at: "; rosie.print(); cout << "\nThe spots are at: " << endl; for( int i=0; i