// Each different input train configuration to Separate is handled similarly void SeparateTestHelper(TrainCar* &train1, const std::string &which_test) { // UNCOMMENT THIS FUNCTION WHEN YOU'RE READY TO TEST SEPARATE std::cout << "============================================================================" << std::endl; std::cout << "SEPARATE TRAINS " << which_test << std::endl; SanityCheck(train1); // record the original IDs for later comparison and statistics calculation std::vector<int> original = RecordIDs(train1); PrintTrain(train1); float speed_original = CalculateSpeed(train1); TrainCar* train2; TrainCar* train3; Separate(train1, train2, train3); assert (train1 == NULL); SanityCheck(train2); SanityCheck(train3); // record the IDs after separation std::vector<int> left = RecordIDs(train2); std::vector<int> right = RecordIDs(train3); // calculate the number of links, unlinks, and train shifts // (all of these counts should be kept small to minimize train yard costs int num_unlinks, num_links, num_shifts; SeparateStatistics(original, left, right, num_unlinks, num_links, num_shifts); std::cout << "Separate Statistics: num unlinks = " << num_unlinks; std::cout << ", num links = " << num_links; std::cout << ", num shifts = " << num_shifts; std::cout << " Total Cost: " << num_unlinks+num_links+num_shifts << std::endl; float speed_left = CalculateSpeed(train2); float speed_right = CalculateSpeed(train3); float left_percent = 100.0 * (speed_original-speed_left) / speed_original; float right_percent = 100.0 * (speed_original-speed_right) / speed_original; if (speed_left < 0.99*speed_original) { assert (speed_right > speed_original); std::cout << "left train is " << std::setprecision(1) << std::fixed << left_percent << "% slower than the original and the right train is " << std::setprecision(1) << std::fixed << -right_percent << "% faster than the original." << std::endl; } else if (speed_right < 0.99*speed_original) { assert (speed_left > speed_original); std::cout << "right train is " << std::setprecision(1) << std::fixed << right_percent << "% slower than the original and the left train is " << std::setprecision(1) << std::fixed << -left_percent << "% faster than the original." << std::endl; } else { std::cout << " left and right train speeds are equal to the original." << std::endl; } PrintTrain(train2); PrintTrain(train3); // cleanup memory usage DeleteAllCars(train2); DeleteAllCars(train3); }
// This function takes a random number generator to create variety in // the freight car weights void ShipFreightHelper(MTRand_int32 &mtrand, int num_engines, int num_cars, int min_speed, int max_cars_per_train) { // UNCOMMENT THIS FUNCTION WHEN YOU'RE READY TO TEST SHIP FREIGHT // create a chain with specified # of engines engines TrainCar* all_engines = NULL; for (int i = 0; i < num_engines; i++) { PushBack(all_engines, TrainCar::MakeEngine()); } // create a chain with specified # of freight cars TrainCar* all_freight = NULL; for (int i = 0; i < num_cars; i++) { // the weight for each car is randomly generated in the range of 30->100 tons int weight = 30 + (mtrand()%15)*5; PushBack(all_freight, TrainCar::MakeFreightCar(weight)); } // rearrange the two structures into a collection of trains // with the specified minimum speed & specified maximum length 12 cars std::vector<TrainCar*> trains = ShipFreight(all_engines, all_freight, min_speed, max_cars_per_train); // when finished, we have either used up all of the engines, or // shipped all the freight (or both!) assert (all_engines == NULL || all_freight == NULL); // print the remaining engines or freight cars if (all_engines != NULL) { std::cout << "Remaining Unused Engines:" << std::endl; SanityCheck(all_engines); PrintTrain(all_engines); } if (all_freight != NULL) { std::cout << "Remaining UnShipped Freight:" << std::endl; SanityCheck(all_freight); PrintTrain(all_freight); } // print the trains std::cout << "Prepared Trains for Shipment:" << std::endl; for (unsigned int i = 0; i < trains.size(); i++) { SanityCheck(trains[i]); PrintTrain(trains[i]); // check that the speed and length rules are followed int total_weight,num_engines,num_freight_cars,num_passenger_cars,num_dining_cars,num_sleeping_cars; TotalWeightAndCountCars(trains[i],total_weight,num_engines,num_freight_cars,num_passenger_cars,num_dining_cars,num_sleeping_cars); int total_cars = num_engines+num_freight_cars+num_passenger_cars+num_dining_cars+num_sleeping_cars; float speed = CalculateSpeed(trains[i]); assert (total_cars <= max_cars_per_train); assert (speed >= min_speed); } // fully delete all TrainCar nodes to prevent memory leaks DeleteAllCars(all_engines); DeleteAllCars(all_freight); for (unsigned int i = 0; i < trains.size(); i++) { DeleteAllCars(trains[i]); } }
void DeleteAllCars(TrainCar* simple){ if(simple!=NULL){ TrainCar* tmp=simple->next; //simple->next->prev=tmp; delete simple; simple=tmp; DeleteAllCars(simple); } else return; }
void SimpleTrainTest() { std::cout << "============================================================================" << std::endl; std::cout << "SIMPLE TRAIN TEST" << std::endl; // create a train with 6 dynamically-allocated cars in a doubly-linked list structure TrainCar* simple = NULL; PushBack(simple, TrainCar::MakeEngine()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakeDiningCar()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakeSleepingCar()); // inspect the cars, the links, the links, and sequential IDs... assert (simple->isEngine()); assert (simple->prev == NULL); assert (simple->next->isPassengerCar()); assert (simple->next->prev->isEngine()); assert (simple->next->next->isPassengerCar()); assert (simple->next->next->next->isDiningCar()); assert (simple->next->next->next->next->isPassengerCar()); assert (simple->next->next->next->next->next->isSleepingCar()); assert (simple->next->next->next->next->next->next == NULL); assert (simple->next->getID() == simple->getID()+1); assert (simple->next->next->getID() == simple->next->getID()+1); assert (simple->next->next->next->getID() == simple->next->next->getID()+1); assert (simple->next->next->next->next->getID() == simple->next->next->next->getID()+1); assert (simple->next->next->next->next->next->getID() == simple->next->next->next->next->getID()+1); // helper routine sanity check & print the results SanityCheck(simple); PrintTrain(simple); // fully delete all TrainCar nodes to prevent a memory leak DeleteAllCars(simple); }
void StudentTests() { std::cout << "============================================================================" << std::endl; std::cout << "STUDENT TESTS" << std::endl; std::cout << "POPBACK TEST...\n" << std::endl; TrainCar* simple = NULL; PushBack(simple, TrainCar::MakeEngine()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakeDiningCar()); PushBack(simple, TrainCar::MakePassengerCar()); PushBack(simple, TrainCar::MakeSleepingCar()); PrintTrain(simple); TrainCar* tmp = PopLastCar(simple); PrintTrain(simple); PrintTrain(tmp); PushFront(simple, tmp); PrintTrain(simple); SanityCheck(simple); std::cout << "\nPOPFRONT TEST... \n" << std::endl; TrainCar* simple2 = NULL; PushBack(simple2, TrainCar::MakeEngine()); PushBack(simple2, TrainCar::MakePassengerCar()); PushBack(simple2, TrainCar::MakePassengerCar()); PushBack(simple2, TrainCar::MakeDiningCar()); PushBack(simple2, TrainCar::MakePassengerCar()); PushBack(simple2, TrainCar::MakeSleepingCar()); PrintTrain(simple2); TrainCar* tmp2 = PopFrontCar(simple2); PrintTrain(simple2); PrintTrain(tmp2); PushFront(simple2, tmp2); PrintTrain(simple2); SanityCheck(simple2); std::cout << "\nPOP TEST" << std::endl; TrainCar* simple3 = NULL; PushBack(simple3, TrainCar::MakeEngine()); PushBack(simple3, TrainCar::MakePassengerCar()); PushBack(simple3, TrainCar::MakePassengerCar()); PushBack(simple3, TrainCar::MakeDiningCar()); PushBack(simple3, TrainCar::MakePassengerCar()); PushBack(simple3, TrainCar::MakeSleepingCar()); PrintTrain(simple3); int ID=simple3->getID(); TrainCar* tmp3 = PopCar(simple3, ID); PrintTrain(simple3); PrintTrain(tmp3); PushFront(simple3, tmp3); PrintTrain(simple3); SanityCheck(simple3); DeleteAllCars(simple); DeleteAllCars(simple2); DeleteAllCars(simple3); std::cout << "StudentTests complete" << std::endl; }