Add ElevatorController
[cs356-p1-elevator.git] / elevatorcontroller.cpp
1 #include "elevatorcontroller.hpp"
2
3 ElevatorController::ElevatorController (int floors, int elevators)
4         : number_of_floors_(floors)
5         , number_of_elevators_(elevators)
6         , elevators_()
7 {
8         /* Seed the RNG */
9         std::srand ( std::time (NULL) );
10
11         /* Create and add all of the elevators */
12         for (int i=0; i<number_of_elevators_; i++)
13                 elevators_.push_back (Elevator());
14 }
15
16 static int choose_random_number_in_range (int low, int high)
17 {
18         return std::rand () % high + low;
19 }
20
21 void ElevatorController::call_elevator_to (int floor, Direction direction)
22 {
23         std::cout << "Called elevator to: floor=" << floor << " direction=" << direction << std::endl;
24
25         /* Check the parameters */
26         if (floor < 0 || floor > number_of_floors_)
27                 throw bad_floor ();
28
29         ElevatorList::iterator it;
30         std::vector<Elevator*> idle_elevators;
31         Stop requested_stop(floor, direction);
32
33         /* Find all idle Elevators */
34         for (it = elevators_.begin(); it != elevators_.end(); it++)
35                 if (it->is_idle ())
36                         idle_elevators.push_back (&(*it));
37
38         if (idle_elevators.size() > 0)
39         {
40                 int num = choose_random_number_in_range (0, idle_elevators.size());
41
42                 idle_elevators.at (num) -> stop_at (requested_stop);
43                 return;
44         }
45
46         /* Find the Elevator which is closest to the requested Stop */
47         bool found = false;
48         float distance = INT_MAX;
49         Elevator *e;
50
51         for (it = elevators_.begin(); it != elevators_.end(); it++)
52         {
53                 if (it->distance_from (requested_stop) < distance)
54                 {
55                         found = true;
56                         distance = it->distance_from (requested_stop);
57                         e = &(*it);
58                 }
59         }
60
61         /* If we found one, send the closest Elevator */
62         if (found)
63         {
64                 e->stop_at (requested_stop);
65                 return;
66         }
67
68         /* Now we're having really bad luck. No elevators are idle, and none are closer than
69          * any other. A random choice will have to do. */
70         int num = choose_random_number_in_range (0, elevators_.size());
71         Elevator &e_ref = elevators_.at (num);
72
73         e_ref.stop_at (requested_stop);
74 }
75
76 void ElevatorController::elevator_request (int elevator_number, int floor)
77 {
78         std::cout << "Request that elevator=" << elevator_number << " stop at floor=" << floor << std::endl;
79
80         /* Check the parameters */
81         if (elevator_number < 0 || elevator_number > number_of_elevators_)
82                 throw bad_elevator ();
83
84         if (floor < 0 || floor > number_of_floors_)
85                 throw bad_floor ();
86
87         /* Construct the Stop to use */
88         Stop s(floor, ALL);
89
90         /* Get the Elevator */
91         Elevator &e = elevators_.at (elevator_number);
92
93         /* Tell it where to stop */
94         e.stop_at (s);
95 }
96
97 void ElevatorController::move_elevators ()
98 {
99         ElevatorList::iterator it;
100
101         for (it = elevators_.begin(); it != elevators_.end(); it++)
102                 it->move();
103 }
104
105 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */