BUGFIX: Elevators did not handle Requests in the correct order
[cs356-p1-elevator.git] / elevatorcontroller.cpp
index d5f760c..9134efb 100644 (file)
@@ -26,6 +26,64 @@ void ElevatorController::call_elevator_to (int floor, Direction direction)
        if (floor < 0 || floor > number_of_floors_)
                throw bad_floor ();
 
+       ElevatorList::iterator it;
+       std::vector<Elevator*> low_load_elevators;
+       Stop requested_stop (floor, direction);
+       const int max_load = number_of_floors_ / 3;
+
+       std::cout << "Using max load: " << max_load << std::endl;
+
+       /* Find all elevators with "low load" */
+       for (it=elevators_.begin(); it != elevators_.end(); it++)
+       {
+               if (it->getLoad() <= max_load)
+                       low_load_elevators.push_back (&(*it));
+       }
+
+       std::vector<Elevator*>::iterator lle_it;
+       bool found = false;
+       float distance = INT_MAX;
+       Elevator *e;
+       int num;
+
+       /* Make sure there are lightly loaded elevators */
+       if (low_load_elevators.size() > 0)
+       {
+               /* Find the closest lightly loaded elevator */
+               for (lle_it = low_load_elevators.begin(); lle_it != low_load_elevators.end(); lle_it++)
+               {
+                       if ((*lle_it)->distance_from (requested_stop) < distance)
+                       {
+                               found = true;
+                               distance = (*lle_it)->distance_from (requested_stop);
+                               e = *lle_it;
+                       }
+               }
+
+               /* Found a closest one, send it */
+               if (found)
+               {
+                       std::cout << "Found closest LLE" << std::endl;
+                       e->stop_at (requested_stop);
+                       return;
+               }
+
+               /* No closest one, so send randomly */
+               std::cout << "No closest LLE: choosing randomly" << std::endl;
+               num = choose_random_number_in_range (0, low_load_elevators.size());
+               low_load_elevators.at (num) -> stop_at (requested_stop);
+               return;
+       }
+
+       /* There were no lightly loaded elevators, so just choose randomly */
+       std::cout << "No LLE at all, choosing randomly" << std::endl;
+       num = choose_random_number_in_range (0, elevators_.size());
+       Elevator &e_ref = elevators_.at (num);
+
+       e_ref.stop_at (requested_stop);
+       return;
+
+#ifdef ALGORITHM_IDLE
        ElevatorList::iterator it;
        std::vector<Elevator*> idle_elevators;
        Stop requested_stop(floor, direction);
@@ -33,10 +91,44 @@ void ElevatorController::call_elevator_to (int floor, Direction direction)
        /* Find all idle Elevators */
        for (it = elevators_.begin(); it != elevators_.end(); it++)
                if (it->is_idle ())
+               {
+                       /* If we have an IDLE elevator that is currently sitting at the
+                        * requested floor, we should obviously send that. */
+                       if (it->distance_from (requested_stop) == 0)
+                       {
+                               it->stop_at (requested_stop);
+                               return;
+                       }
+
+                       /* Was not at the right floor, but still is a good cantidate */
                        idle_elevators.push_back (&(*it));
+               }
 
        if (idle_elevators.size() > 0)
        {
+               std::vector<Elevator*>::iterator idle_it;
+               bool found = false;
+               float distance = INT_MAX;
+               Elevator *e;
+
+               /* Try to send the closest IDLE elevator */
+               for (idle_it=idle_elevators.begin(); idle_it!=idle_elevators.end(); idle_it++)
+               {
+                       if ((*idle_it)->distance_from (requested_stop) < distance)
+                       {
+                               found = true;
+                               distance = (*idle_it)->distance_from (requested_stop);
+                               e = *idle_it;
+                       }
+               }
+
+               if (found)
+               {
+                       e->stop_at (requested_stop);
+                       return;
+               }
+
+               /* No closest IDLE elevator was found, so choose one randomly */
                int num = choose_random_number_in_range (0, idle_elevators.size());
 
                idle_elevators.at (num) -> stop_at (requested_stop);
@@ -71,6 +163,7 @@ void ElevatorController::call_elevator_to (int floor, Direction direction)
        Elevator &e_ref = elevators_.at (num);
 
        e_ref.stop_at (requested_stop);
+#endif
 }
 
 void ElevatorController::elevator_request (int elevator_number, int floor)
@@ -102,4 +195,15 @@ void ElevatorController::move_elevators ()
                it->move();
 }
 
+bool ElevatorController::oneElevatorWillStillStopAt (int floor, Direction direction) const
+{
+       ElevatorList::const_iterator it;
+
+       for (it=elevators_.begin(); it!=elevators_.end(); it++)
+               if (it->willStopAt (floor, direction))
+                       return true;
+
+       return false;
+}
+
 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */