// File: p4main3.cpp // // Last update: 02/26/2007 20:02 // Last update: 04/15/2007 01:45 // // See Project 2 & 4 description for documentation. // #include #include #include #include #include "Thing.h" #include "RaceCourse.h" #include "ScriptedCar.h" using namespace std ; // Vampire cars derive from Car. // // If you bump into a Vampire car it sucks all your fuel. // If Vampire cars run out of fuel, they rest for 1 turn // and their fuel regenerates. // // This stuff should be in a different file, but // it keeps the test program simple if I put it // all in one place. -R. class Vampire : public Car { public: Vampire() ; Vampire(unsigned int row, unsigned int col) ; void encounter(Car *ptr) ; virtual void MakeMove() ; bool IsRested() ; protected: bool rested ; // rested one turn? unsigned int move ; // move number static const unsigned int initfuel ; } ; const unsigned int Vampire::initfuel = 20 ; Vampire::Vampire() : rested(false), move(0) { // do nothing } Vampire::Vampire(unsigned int row, unsigned int col) : Car(row,col,'V',initfuel), rested(false), move(0) { // do nothing more } void Vampire::encounter(Car *ptr) { unsigned int f ; f = ptr->GetFuelLevel() ; ptr->DecFuelLevel(f) ; // sucks fuel from victim Car IncFuelLevel(initfuel) ; // replenishes own fuel tank rested = false ; } void Vampire::MakeMove() { // Check if we are out of fuel unsigned int f = GetFuelLevel() ; if ((f == 0) && !rested) { // if out of fuel rest for 3 days rested = true ; move-- ; // might not have finished moving that direction return ; } else if ( (f == 0) && rested) { // if rested, fuel regenerates SetFuelLevel(initfuel) ; rested = false ; } switch (move % 6) { case 0 : ZoomUp() ; break ; case 1 : ZoomRight() ; break ; case 2 : ZoomDown() ; break ; case 3 : ZoomUp() ; break ; case 4 : ZoomLeft() ; break ; case 5 : ZoomDown() ; break ; } move++ ; } bool Vampire::IsRested() { return rested ; } // This function initializes the obstacle vector. // The "input" is almost WYSIWYG. // // Warning! Does not check for size compatibility // with RaceCourse constructor. // // Make sure all the rows are the same length. void SetObstacles(vector& obs) { vector V ; // WYSIWYG Obstacle Constructor?? // // 0123456789012345678901 V.push_back("######################") ; V.push_back("# #################") ; V.push_back("# # #") ; V.push_back("# ############ # #") ; V.push_back("# ## # #") ; V.push_back("# ########## ## # #") ; V.push_back("# ## ## # #") ; V.push_back("# ######## ## ## # #") ; V.push_back("# ### ## ## # #") ; V.push_back("###### ### ## ## #####") ; V.push_back("# #") ; V.push_back("# #### ##### ### #") ; V.push_back("# # # #") ; V.push_back("# # ### #########") ; V.push_back("### # # #") ; V.push_back("# ######### #") ; V.push_back("####### # #") ; V.push_back("# # ## #####") ; V.push_back("# ###### # #") ; V.push_back("### # # ###### #") ; V.push_back("# #") ; V.push_back("######################") ; // Set obstacles // No need to set outside perimeter unsigned int i, j, rows, cols ; rows = V.size() ; assert(rows > 0) ; cols = V.at(0).length() ; for (i=1 ; i < rows-1 ; i++) { assert( cols == V.at(i).length() ); for (j = 1 ; j < cols-1 ; j++) { if (V.at(i).at(j) == '#') { obs.push_back(new Wall(i,j)) ; } } } } void UpdateScreen(RaceCourse& R, vector& Cars) { #ifdef VT100 cout << "\033[2J\033[H" ; // VT100 erase screen, goto HOME #endif R.PrettyPrintCourse() ; RaceStatus s = R.GetRaceStatus() ; switch(s) { case WAITING : cout << "Status: WAITING\n" ; break ; case STARTED : cout << "Status: STARTED\n" ; break ; case FINISHED : cout << "Status: FINISHED\n" ; break ; default: cout << "Status: UNKNOWN (Bad)\n" ; } for(unsigned int i=0 ; i < Cars.size() ; i++) { cout << "Car #" << Cars[i]->DrawMe() << " at " ; cout << "(" << Cars[i]->GetRow() << "," << Cars[i]->GetCol() << ")" ; cout << " fuel=" << Cars[i]->GetFuelLevel() << "\n" ; } } int main() { vector obs, morethings ; vector Cars ; ScriptedCar *cptr ; Goal *gptr ; bool AddOK ; // Initialize RaceCourse R RaceCourse R(20, 20) ; // Set up some walls SetObstacles(obs) ; // Set up winning location gptr = new Goal(20, 1) ; obs.push_back(gptr) ; // Tell RaceCourse R to put in the walls, etc. AddOK = R.AddThings(obs) ; if (!AddOK) { cerr << "Something went wrong with AddThings()\n" ; exit(1) ; } // Now we set up some cars // Scripted paths for each car to follow // vector script(4) ; // 0123456789012345 script[0] = "drdldrdlrrdldrrd" ; script[1] = "drdrldrrrdrddldr" ; script[2] = "drdrldrdrdlldrdl" ; script[3] = "drdrdldrdldldlll" ; // Make some Cars // We need both Thing pointers and ScriptedCar pointers // because AddThings takes vector of Thing * only // cptr = new ScriptedCar(1, 1, '0', 70, script[0]) ; Cars.push_back(cptr) ; morethings.push_back(cptr) ; cptr = new ScriptedCar(1, 2, '1', 70, script[1]) ; Cars.push_back(cptr) ; morethings.push_back(cptr) ; cptr = new ScriptedCar(1, 3, '2', 70, script[2]) ; Cars.push_back(cptr) ; morethings.push_back(cptr) ; cptr = new ScriptedCar(1, 4, '3', 70, script[3]) ; Cars.push_back(cptr) ; morethings.push_back(cptr) ; // Add a Vampire to the mix Vampire *vptr = new Vampire(13, 1) ; morethings.push_back(vptr) ; // Tell RaceCourse R to put in the Cars, etc. AddOK = R.AddThings(morethings) ; if (!AddOK) { cerr << "Something went wrong with AddThings()\n" ; exit(1) ; } // Print out starting line up // UpdateScreen(R, Cars) ; cout << "\n\nInitial Race Course: \n" ; cout << "#Rows=" << R.GetNumOfRows() << endl ; cout << "#Cols=" << R.GetNumOfCols() << endl ; cout << "-----------------------------------------\n\n" ; #ifdef VT100 // #define VT100 for "interactive" version. cout << "Type \"enter\" to continue\n" ; cin.ignore(10000, '\n') ; #endif R.StartRace() ; for (unsigned int move=0 ; move < 16 ; move++) { // Vampire makes first move vptr->MakeMove() ; for (unsigned int i=0 ; i < Cars.size() ; i++) { Cars[i]->MakeMove() ; UpdateScreen(R, Cars) ; cout << "Vampire" << " at " ; cout << "(" << vptr->GetRow() << "," << vptr->GetCol() << ")" ; cout << " fuel=" << vptr->GetFuelLevel() ; cout << " rest=" << vptr->IsRested() << "\n" ; cout << "\nCar #" << Cars[i]->DrawMe() << ", Move #" << move << " was '" << script[i][move] << "'\n\n" ; // Check for winner if (gptr->GetWinner() != NULL) { cout << "And the winer is, Car #" << gptr->GetWinner()->DrawMe() << "!!\n" ; } cout << "-----------------------------------------\n\n\n" ; #ifdef VT100 // #define VT100 for "interactive" version. cout << "Type \"enter\" to continue\n" ; cin.ignore(10000, '\n') ; #endif } } // Deallocate memory for cars & Walls // for (unsigned int i=1; i < Cars.size() ; i++) { delete Cars[i] ; } for (unsigned int j=1; j < obs.size() ; j++) { delete obs[j] ; } }