#include #include #include #include #include using namespace std; //////////////////////////////////////////// // // Puppy class definition class puppy{ friend ostream &operator<<(ostream&, puppy); friend istream &operator>>(istream&, puppy &); public: puppy(); string getName(); void setName(string); string getID(); bool setID(string); float getWeight(); void setWeight(float); string getColor(); bool setColor(string); string getSex(); bool setSex(string); bool isNeutered(); void Neuter(); char getStatus(); bool setStatus(char); void inputPuppy(); ~puppy(); private: string name; string id; float weight; string color; string sex; bool neutered; char status; }; // puppy constructor puppy::puppy(){ name ="-"; id = "-"; weight = 0; color = "-"; sex = "-"; neutered = false; status ='-'; } // puppy destructor // Don't need to do anything special here puppy::~puppy(){ // empty destructor } // find out what the puppy is named string puppy::getName(){ return name; } // give the puppy an name of its own void puppy::setName(string newname){ name = newname; } // Each puppy has an ID chip inserted under its skin // and a number tattooed on its ear string puppy::getID(){ return id; } // set the puppies initial ID bool puppy::setID(string newid){ if (newid.length() == 5) { id = newid; return true; } else { cerr << "ID length should be 5" << endl; return false; } } // find the puppies current weight float puppy::getWeight(){ return weight; } // set the puppies current weight void puppy::setWeight(float newweight){ weight = newweight; } // what color is this puppy? string puppy::getColor(){ return color; } // set the puppies color // yellow, black, brown and brindle are the possibilites bool puppy::setColor(string newcolor){ if (newcolor == "black"||newcolor == "Black"|| newcolor =="BLACK"){ color = "Black"; return true; } else if (newcolor == "yellow"|| newcolor == "Yellow" ||newcolor =="YELLOW") { color = "Yellow"; return true; } else if (newcolor == "brown"|| newcolor == "Brown" ||newcolor =="BROWN"){ color = "Brown"; return true; } else if (newcolor == "brindle"|| newcolor == "Brindle" || newcolor =="BRINDLE" ){ color = "Brindle"; return true; } else { cerr << "Illegal color code. Bad code: " << newcolor << endl; return false; } } // What sex is this puppy? string puppy::getSex(){ return sex; } // Set this puppies sex bool puppy::setSex(string newsex){ if (newsex == "male" || newsex == "Male" || newsex == "MALE" || newsex == "M" || newsex =="m") { sex = "Male"; return true; } else if (newsex == "female" || newsex == "Female" || newsex == "FEMALE" || newsex == "f" || newsex =="F") { sex = "Female"; return true; } else { cerr << "Illegal sex code. Bad code: " << newsex << endl; return false; } } // Some puppies are kept for breeding stock, // and are not neutered bool puppy::isNeutered(){ return neutered; } // Other puppies are kept out of trouble void puppy::Neuter(){ neutered = true; } // Keep track of what happened to indivdual pups char puppy::getStatus(){ return status; } // Set the puppy status bool puppy::setStatus(char newstatus){ // Status is one of: // w : puppy in breeding center being whelped // p : released prior to raising // o : puppy out at raiser // r : released from raiser // i : failed IFT, released // a : picked up by ATF // t : puppy in guide training // g : sucessful guide // b : breeding stock if (newstatus == 'w'||newstatus =='W') { status = 'W'; return true; } else if (newstatus == 'p'||newstatus == 'P' ){ status = 'P'; return true; } else if (newstatus == 'o'||newstatus == 'O') { status = 'O'; return true; } else if (newstatus == 'r'||newstatus == 'R') { status = 'R'; return true; } else if (newstatus == 'i'||newstatus == 'I' ) { status = 'I'; return true; } else if (newstatus == 'a'||newstatus == 'A' ){ status = 'A'; return true; } else if (newstatus == 't'||newstatus == 'T') { status = 'T'; return true; } else if (newstatus == 'g'||newstatus == 'G' ){ status = 'G'; return true; } else if (newstatus == 'b'||newstatus == 'B') { status = 'B'; return true; } else { cerr << "Error in setting status code. Bad code: " << newstatus << endl; return false; } } // Make it easy to input puppy information from the keyboard void puppy::inputPuppy(){ string newname, newcolor, newsex, eoln; char neuter, newstatus; cout << "Please enter the puppy information: " << endl; cout << "Puppy name: "; getline (cin, name); do { cout << "Puppy ID: "; getline (cin, id); } while (!setID(id)); cout << "Puppy birth weight: "; cin >> weight; getline (cin, eoln); do { cout << "Puppy color: "; getline (cin, newcolor); } while (!setColor(newcolor)); do { cout << "Puppy sex: "; getline (cin, newsex); } while (!setSex(newsex)); cout << "Is the pup neutered? (y/n) "; cin >> neuter; if (neuter == 'y'||neuter == 'Y') neutered = true; else neutered = false; cout << "Puppy status code: " << endl; cout << " w : puppy in breeding center being whelped" << endl; cout << " p : released prior to raising" << endl; cout << " o : puppy out at raiser" << endl; cout << " r : released from raiser" << endl; cout << " i : failed IFT, released" << endl; cout << " a : picked up by ATF" << endl; cout << " t : in guide training" << endl; cout << " g : sucessful guide " << endl; cout << " b : breeding stock " << endl; do { cout << "Puppy status code: "; cin >> newstatus; } while (!setStatus(newstatus)); getline (cin, eoln); } // overload the output operator ostream &operator<<(ostream &output, puppy p) { string ntd; if (p.neutered) ntd = "Neutered"; else ntd = "Intact"; output << p.name << " " << p.id << " " << p.weight << " " << p.color << " " << p.sex << " " << ntd << " " << p.status; return output; } // overload the input operator istream &operator>>(istream &input, puppy &p){ string ntd; input >> p.name >> p.id >> p.weight >> p.color >> p.sex >> ntd >> p.status; if (ntd == "Intact") p.neutered = false; else p.neutered = true; return input; } // // end the puppy class definition //////////////////////////////////////////// //////////////////////////////////////////// // litter class definition // class litter{ friend ostream &operator<<(ostream&, litter); friend istream &operator>>(istream&, litter &); public: litter(); ~litter(); string getFatherName(); string getMotherName(); int getBirthDay(); int getBirthMonth(); int getBirthYear(); void setupLitter(); float getSuccessRate(); void saveLitter(string); void loadLitter(string); void print(); void clear(); int getLitterSize(); // Additions to the class for pro2ject 5 char getLitterStatus(); int changePupStatus(string, char); litter * getNextLitter(); void setNextLitter(litter *); private: string fathername; string mothername; int birth_day; int birth_month; int birth_year; vector puppies; // addition for project 5 litter * nextLitter; }; litter::litter(){ fathername ="-"; mothername ="-"; birth_day = 0; birth_month = 0; birth_year = 0; puppies.clear(); nextLitter = NULL; } // what is the father's name? string litter::getFatherName(){ return fathername; } // what is the mother's name? string litter::getMotherName(){ return mothername; } // return information about birth dates int litter::getBirthDay(){ return birth_day; } int litter::getBirthMonth(){ return birth_month; } int litter::getBirthYear(){ return birth_year; } // This method takes information about // the litter from the keyboard void litter::setupLitter(){ int number_of_pups; puppy temp_pup; string eoln; cout << "Please enter the following information about the litter:" << endl; cout << "Father's name: "; getline (cin, fathername); cout << "Mother's name: "; getline (cin, mothername); cout << "Day of birth: "; cin >> birth_day; cout << "Month of birth: "; cin >> birth_month; cout << "Year of birth: "; cin >> birth_year; cout << "Number of puppies: "; cin >> number_of_pups; getline(cin, eoln); for (int i = 0; i < number_of_pups; i++){ temp_pup.inputPuppy(); puppies.push_back(temp_pup); } } // This method computes the success rate of puppies in the litter // The success rate is the percentage of pups who are guides or // breeding stock. float litter::getSuccessRate(){ float result = 0; int successful_pups = 0; for (int i = 0; i < puppies.size(); i++) { if (puppies[i].getStatus() == 'G' || puppies[i].getStatus() == 'B') successful_pups ++; } result = ((float) successful_pups)/ puppies.size(); // WTF? static_cast isn't working for some reason. //result = (static_cast successful_pups)/ puppies.size(); return result; } // this method write the litter information // out to a file void litter::saveLitter(string litterfile){ ofstream outfile; outfile.open(litterfile.c_str()); if (!outfile) { cerr << "Could not open file: "<< litterfile << " for output." << endl; exit(1); } outfile << fathername << endl; outfile << mothername << endl; outfile << birth_day << endl; outfile << birth_month << endl; outfile << birth_year << endl; outfile << puppies.size() << endl; for (int i = 0; i < puppies.size(); i++) outfile << puppies[i] << endl; outfile.close(); } // this method loads information about a litter from a file void litter::loadLitter(string litterfile){ string eoln; puppy temp_pup; int litter_size; ifstream infile; infile.open(litterfile.c_str()); if (!infile) { cerr << "Could not open file: "<< litterfile << " for input." << endl; exit(1); } getline(infile, fathername); getline(infile, mothername); infile >> birth_day; infile >> birth_month; infile >> birth_year; infile >> litter_size; getline(infile, eoln); for (int i = 0; i < litter_size; i++){ infile >> temp_pup; puppies.push_back(temp_pup); } infile.close(); } // Erases all the old information in a litter void litter::clear(){ fathername ="-"; mothername ="-"; birth_day = 0; birth_month = 0; birth_year = 0; puppies.clear(); } // Prints the litter information out to the screen, neatly void litter::print(){ char sl = '/'; cout << endl; cout << "Fathername: " << fathername << endl; cout << "Mother's name: " << mothername << endl; cout << "Birthdate: " << birth_month<< sl << birth_day << sl << birth_year << endl; for (int i = 0; i < getLitterSize(); i++) cout << puppies[i] << endl; cout << endl; } // how many siblings? // this method knows. int litter::getLitterSize(){ return puppies.size(); } // Determines which status a particular litter is in // Returns: // B for breeding center // R for out at raisers // T for in training // W for working // F for released char litter::getLitterStatus(){ int W = 0, O =0, T = 0, G = 0, B = 0; for (int i = 0; i < puppies.size(); i++){ switch (puppies[i].getStatus()){ case 'W': W++; break; case 'O': O++; break; case 'T': T++; break; case 'G': G++; break; case 'B': B++; break; default: // some other code, probably a fail code ; } } // Released litter has no puppies with a W, O, T, G or B code // return F for failed if (0 == W && 0 == O && 0 == T &&0 == G && 0 == B) return 'F'; // A litter being whelped has at least one pup with a W // Return a B for the breeding center if (W > 0) return ('B'); // A raising litter has no Ws but at least one O // return R for raising if (0 == W && O > 0) return 'R'; // A training litter has no W or O but at least one T // Return T for training if (0 == W && 0 == O && T > 0) return 'T'; // A working litter has only G or B pups // Return W for working if (0 == W && 0 == O && 0 == T && (G > 0|| B > 0)) return 'W'; cerr << " Some litter didn't match a litter status. WTF?" << endl; cerr << "Numbers were:\nW: " << W << "\nO: " << O << "\nT: " << T << "\nG: " << G << "\nB: " << B << endl; } // Change the status of a particular puppy // 1 if change happens // 0 if puppy not found // -1 if status code is found to be bad int litter::changePupStatus(string pup_id, char newstatus){ bool status_ret_code; for (int i = 0; i < puppies.size(); i++){ if (puppies[i].getID() == pup_id){ status_ret_code = puppies[i].setStatus(newstatus); if (status_ret_code) return 1; else return -1; } } return 0; } litter::~litter(){ // empty deconstructor } litter * litter::getNextLitter() { return nextLitter; } void litter::setNextLitter(litter * newLitter){ nextLitter = newLitter; } // overload the output operator ostream &operator<<(ostream &output, litter l) { output << l.fathername << " " << l.mothername << " " << l.birth_day << " " << l.birth_month << " " << l.birth_year << " " << l.getLitterSize() << endl; for (int i = 0; i < l.getLitterSize(); i++) output << l.puppies[i] << endl; return output; } // overload the input operator istream &operator>>(istream &input, litter &l){ int num_pups; puppy temp_pup; input >> l.fathername >> l.mothername >> l.birth_day >> l.birth_month >> l.birth_year >> num_pups; for (int i = 0; i < num_pups; i++) { input >> temp_pup; l.puppies.push_back(temp_pup); } return input; } // // end the litter class definition //////////////////////////////////////////// //////////////////////////////////////////// // Kennel class // class kennel{ public: kennel(); ~kennel(); void newLitter(); int changePupStatus(string,char); void print(); void showBreeding(); void showRaising(); void showTraining(); void showWorking(); void showReleased(); void test(); private: void deleteList(litter * &); void printList(litter *); void sortLitter(litter *); int changePupOnList(string,char, litter *); void updateReleasedList(); void updateBreedingList(); void updateRaisingList(); void updateTrainingList(); void updateWorkingList(); // new litters start out in the breeding center litter * breeding; // after all are whelped, they move to the raisers litter * raising; // after all puppies are raised, they go into training litter * training; // after puppies are trained, they go into work litter * working; // sometimes, a whole litter washes out litter * released; }; // This was just a method that I could use to make public // calls to activate and test private methods. void kennel::test(){ deleteList(training); } // default constructor, just set the lists to NULL kennel::kennel(){ breeding = NULL; raising = NULL; training = NULL; working = NULL; released = NULL; } // Destructors are needed now! // we have to traverse each list and delete // each element on it kennel::~kennel(){ deleteList(breeding); deleteList(raising); deleteList(training); deleteList(working); deleteList(released); } // end the kennel deconstructor // Search a list to find if a puppy is on it // Returns -1 for bad status code, // 0 if puppy isn't found // 1 if change is successful int kennel::changePupOnList(string pup_id, char new_status, litter * list){ int return_status; litter * temp; // traverse the list temp = list; while (temp != NULL){ return_status = temp->changePupStatus(pup_id, new_status); if (-1 == return_status) // code returned as bad return -1; else if (1 == return_status) // found the pup we were looking for return 1; else // look at the next litter temp = temp->getNextLitter(); } // if we haven't found it yet, it isn't on this list return 0; } // change the status of a puppy. Since we don't know where the puppy is, // Just try it on each litter in each list until we find the puppy or // run out of litters to try. // Returns -1 for bad status code, // 0 if puppy isn't found // 1 if change is successful // After we find the pup and change its status, we need to // traverse the list and see if the litter should change to a // different list int kennel::changePupStatus(string pup_id, char new_status){ int return_val; return_val = changePupOnList(pup_id, new_status, released); if (-1 == return_val ) return -1; else if (1 == return_val){ cerr << "updating released" << endl; updateReleasedList(); return 1; } return_val = changePupOnList(pup_id, new_status, breeding); if (-1 == return_val ) return -1; else if (1 == return_val){ cerr << "updating breeding" << endl; updateBreedingList(); return 1; } return_val = changePupOnList(pup_id, new_status, raising); if (-1 == return_val ) return -1; else if (1 == return_val){ cerr << "updating raising" << endl; updateRaisingList(); return 1; } return_val = changePupOnList(pup_id, new_status, training); if (-1 == return_val ) return -1; else if (1 == return_val){ cerr << "updating training" << endl; updateTrainingList(); return 1; } return_val = changePupOnList(pup_id, new_status, working); if (-1 == return_val ) return -1; else if (1 == return_val){ cerr << "updating working" << endl; updateWorkingList(); return 1; } // if we didn't return above, then we never found the puppy return 0; } // Something changed on the released list, // see if that changes the litter status // Assumes that only one litter might have changed void kennel::updateReleasedList(){ litter * temp, * last; // check the first node to see if it changed if (released->getLitterStatus() != 'R'){ temp = released; released = released->getNextLitter(); temp->setNextLitter(NULL); sortLitter(temp); return; } // If the first litter didn't change, some other did //Traverse the whole list, checking the status of each litter // to see if one changed last = released; temp = released->getNextLitter(); while (temp != NULL){ if (temp->getLitterStatus() != 'R'){ last->setNextLitter(temp->getNextLitter()); temp->setNextLitter(NULL); sortLitter(temp); return; } last=temp; temp = temp->getNextLitter(); } } // Update the breeding list to see if any ONE // litter has changed void kennel::updateBreedingList(){ litter * temp, * last; // check the first node to see if it changed if (breeding->getLitterStatus() != 'B'){ temp = breeding; breeding = breeding->getNextLitter(); temp->setNextLitter(NULL); sortLitter(temp); return; } // If the first litter didn't change, some other did //Traverse the whole list, checking the status of each litter // to see if one changed last = breeding; temp = breeding->getNextLitter(); while (temp != NULL){ if (temp->getLitterStatus() != 'B'){ last->setNextLitter(temp->getNextLitter()); temp->setNextLitter(NULL); sortLitter(temp); return; } last=temp; temp = temp->getNextLitter(); } } // Check the raising list, and move any litter off that has changed // one litter only void kennel::updateRaisingList(){ litter * temp, * last; // check the first node to see if it changed if (raising->getLitterStatus() != 'R'){ temp = raising; raising = raising->getNextLitter(); temp->setNextLitter(NULL); sortLitter(temp); return; } // If the first litter didn't change, some other did //Traverse the whole list, checking the status of each litter // to see if one changed last = raising; temp = raising->getNextLitter(); while (temp != NULL){ if (temp->getLitterStatus() != 'R'){ last->setNextLitter(temp->getNextLitter()); temp->setNextLitter(NULL); sortLitter(temp); return; } last=temp; temp = temp->getNextLitter(); } } // Update the training list and see if any one litter needs to be // moved to a different list void kennel::updateTrainingList(){ litter * temp, * last; // check the first node to see if it changed if (training->getLitterStatus() != 'T'){ cerr << "in first case" << endl; temp = training; training = training->getNextLitter(); temp->setNextLitter(NULL); sortLitter(temp); return; } // If the first litter didn't change, some other did //Traverse the whole list, checking the status of each litter // to see if one changed cerr << "after" << endl; last = training; temp = training->getNextLitter(); while (temp != NULL){ if (temp->getLitterStatus() != 'T'){ last->setNextLitter(temp->getNextLitter()); temp->setNextLitter(NULL); sortLitter(temp); return; } last=temp; temp = temp->getNextLitter(); } } // If you have been reading the comment above, you should // have a good idea of what this method does to any ONE litter // on the list void kennel::updateWorkingList(){ litter * temp, * last; // check the first node to see if it changed if (working->getLitterStatus() != 'W'){ temp = working; working = working->getNextLitter(); temp->setNextLitter(NULL); sortLitter(temp); return; } // If the first litter didn't change, some other did //Traverse the whole list, checking the status of each litter // to see if one changed last = working; temp = working->getNextLitter(); while (temp != NULL){ if (temp->getLitterStatus() != 'W'){ last->setNextLitter(temp->getNextLitter()); temp->setNextLitter(NULL); sortLitter(temp); return; } last=temp; temp = temp->getNextLitter(); } } // This method makes a new litter and // adds it to the right list void kennel::newLitter(){ // make a new litter litter * new_litter = new(litter); litter * place; // get the litter information new_litter->setupLitter(); // sort litter to right place sortLitter(new_litter); } // print the breeding list void kennel::showBreeding(){ printList(breeding); } // print the raising list void kennel::showRaising(){ printList(raising); } // print the training list void kennel::showTraining(){ printList(training); } // print the working list void kennel::showWorking(){ printList(working); } // print the released list void kennel::showReleased(){ printList(released); } // figure out where the litter goes // Can be one of the five lists void kennel::sortLitter(litter * new_litter){ switch (new_litter->getLitterStatus()){ case 'F': // Add this litter to the released list new_litter->setNextLitter(released); released = new_litter; break; case 'B': // Add this litter to the breeding list new_litter->setNextLitter(breeding); breeding = new_litter; break; case 'R': // Add this litter to the raising list new_litter->setNextLitter(raising); raising = new_litter; break; case 'T': // Add this litter to the training list new_litter->setNextLitter(training); training = new_litter; break; case 'W': // Add this litter to the working list cerr << "adding to working" << endl; new_litter->setNextLitter(working); working = new_litter; cerr << "printing working" << endl; printList(working); break; default: cerr << "Bad litter status in sortLitter. Code: " << new_litter->getLitterStatus() << endl; } } // empty all elemets of a list of litters void kennel::deleteList(litter * & kill_this){ litter * next_to_die; while (kill_this != NULL){ next_to_die = kill_this->getNextLitter(); delete (kill_this); kill_this = next_to_die; } kill_this = NULL; } // print all the elements on the list of litters neatly. void kennel::printList(litter * print_this){ if (print_this == NULL) cout << "None." << endl; else while (print_this != NULL){ print_this->print(); print_this = print_this->getNextLitter(); } } // print out all the litters in a kennel void kennel::print(){ cout << "Litters in the breeding center:" << endl; printList(breeding); cout << "Litters at raisers: " << endl; printList(raising); cout << "Litters in training: " << endl; printList(training); cout << "Litters out working" << endl; printList(working); cout << "Litters that were released: " << endl; printList(released); } // // end the kennel class //////////////////////////////////////////// //////////////////////////////////////////// // Main funtion // int main(){ kennel k; char choice; string pupID; char newstatus; cout << "Welcome to the litter tracking program" << endl; cout << "This program tracks litters as they move between" << endl; cout << "the breeding center, being distributed to raisers," << endl; cout << "going into training, going to work, or washing out." << endl; while (!0){ cout << "Please enter your choice:" << endl; cout << "A) Add a new litter" << endl; cout << "U) Update a particular puppy" << endl << endl; cout << "B) Show litters at Breeding center" << endl; cout << "R) Show all litters at raisers" << endl; cout << "T) Show all litters in training" << endl; cout << "W) Show all working litters" << endl; cout << "F) Show all released litters" << endl; cout << "*) Show all litters" << endl; cout << "Q) quit" << endl; cout << endl; cout << "Your choice: "; cin >> choice; cin.ignore(); switch (choice){ case 'x': k.test(); break; case 'A': case 'a': k.newLitter(); cout << endl; break; case 'U': case 'u': cout << "Enter puppy ID to change: " << endl; getline(cin,pupID); cout << "Enter new puppy status: "; cin >> newstatus; cin.ignore(); k.changePupStatus(pupID, newstatus); break; case 'B': case 'b': k.showBreeding(); cout << endl; break; case 'R': case 'r': k.showRaising(); cout << endl; break; case 'T': case 't': k.showTraining(); cout << endl; break; case 'W': case 'w': k.showWorking(); cout << endl; break; case 'F': case 'f': k.showReleased(); cout << endl; break; case '*': k.print(); cout << endl; break; case 'Q': case 'q': return 0; default: cout << "Incorrect choice code" << endl; } } }