1 #include "elevatorcontroller.hpp"
3 ElevatorController::ElevatorController (int floors, int elevators)
4 : number_of_floors_(floors)
5 , number_of_elevators_(elevators)
9 std::srand ( std::time (NULL) );
11 /* Create and add all of the elevators */
12 for (int i=0; i<number_of_elevators_; i++)
13 elevators_.push_back (Elevator(i));
16 static int choose_random_number_in_range (int low, int high)
18 return std::rand () % high + low;
21 void ElevatorController::call_elevator_to (int floor, Direction direction)
23 std::cout << "Called elevator to: floor=" << floor << " direction=" << direction << std::endl;
25 /* Check the parameters */
26 if (floor < 0 || floor > number_of_floors_)
29 ElevatorList::iterator it;
30 std::vector<Elevator*> low_load_elevators;
31 Stop requested_stop (floor, direction);
32 const int max_load = number_of_floors_ / 3;
34 std::cout << "Using max load: " << max_load << std::endl;
36 /* Find all elevators with "low load" */
37 for (it=elevators_.begin(); it != elevators_.end(); it++)
39 if (it->getLoad() <= max_load)
40 low_load_elevators.push_back (&(*it));
43 std::vector<Elevator*>::iterator lle_it;
45 float distance = INT_MAX;
49 /* Make sure there are lightly loaded elevators */
50 if (low_load_elevators.size() > 0)
52 /* Find the closest lightly loaded elevator */
53 for (lle_it = low_load_elevators.begin(); lle_it != low_load_elevators.end(); lle_it++)
55 if ((*lle_it)->distance_from (requested_stop) < distance)
58 distance = (*lle_it)->distance_from (requested_stop);
63 /* Found a closest one, send it */
66 std::cout << "Found closest LLE" << std::endl;
67 e->stop_at (requested_stop);
71 /* No closest one, so send randomly */
72 std::cout << "No closest LLE: choosing randomly" << std::endl;
73 num = choose_random_number_in_range (0, low_load_elevators.size());
74 low_load_elevators.at (num) -> stop_at (requested_stop);
78 /* There were no lightly loaded elevators, so just choose randomly */
79 std::cout << "No LLE at all, choosing randomly" << std::endl;
80 num = choose_random_number_in_range (0, elevators_.size());
81 Elevator &e_ref = elevators_.at (num);
83 e_ref.stop_at (requested_stop);
87 ElevatorList::iterator it;
88 std::vector<Elevator*> idle_elevators;
89 Stop requested_stop(floor, direction);
91 /* Find all idle Elevators */
92 for (it = elevators_.begin(); it != elevators_.end(); it++)
95 /* If we have an IDLE elevator that is currently sitting at the
96 * requested floor, we should obviously send that. */
97 if (it->distance_from (requested_stop) == 0)
99 it->stop_at (requested_stop);
103 /* Was not at the right floor, but still is a good cantidate */
104 idle_elevators.push_back (&(*it));
107 if (idle_elevators.size() > 0)
109 std::vector<Elevator*>::iterator idle_it;
111 float distance = INT_MAX;
114 /* Try to send the closest IDLE elevator */
115 for (idle_it=idle_elevators.begin(); idle_it!=idle_elevators.end(); idle_it++)
117 if ((*idle_it)->distance_from (requested_stop) < distance)
120 distance = (*idle_it)->distance_from (requested_stop);
127 e->stop_at (requested_stop);
131 /* No closest IDLE elevator was found, so choose one randomly */
132 int num = choose_random_number_in_range (0, idle_elevators.size());
134 idle_elevators.at (num) -> stop_at (requested_stop);
138 /* Find the Elevator which is closest to the requested Stop */
140 float distance = INT_MAX;
143 for (it = elevators_.begin(); it != elevators_.end(); it++)
145 if (it->distance_from (requested_stop) < distance)
148 distance = it->distance_from (requested_stop);
153 /* If we found one, send the closest Elevator */
156 e->stop_at (requested_stop);
160 /* Now we're having really bad luck. No elevators are idle, and none are closer than
161 * any other. A random choice will have to do. */
162 int num = choose_random_number_in_range (0, elevators_.size());
163 Elevator &e_ref = elevators_.at (num);
165 e_ref.stop_at (requested_stop);
169 void ElevatorController::elevator_request (int elevator_number, int floor)
171 std::cout << "Request that elevator=" << elevator_number << " stop at floor=" << floor << std::endl;
173 /* Check the parameters */
174 if (elevator_number < 0 || elevator_number > number_of_elevators_)
175 throw bad_elevator ();
177 if (floor < 0 || floor > number_of_floors_)
180 /* Construct the Stop to use */
183 /* Get the Elevator */
184 Elevator &e = elevators_.at (elevator_number);
186 /* Tell it where to stop */
190 void ElevatorController::move_elevators ()
192 ElevatorList::iterator it;
194 for (it = elevators_.begin(); it != elevators_.end(); it++)
198 bool ElevatorController::oneElevatorWillStillStopAt (int floor, Direction direction) const
200 ElevatorList::const_iterator it;
202 for (it=elevators_.begin(); it!=elevators_.end(); it++)
203 if (it->willStopAt (floor, direction))
209 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */