Add ElevatorController
authorIra W. Snyder <devel@irasnyder.com>
Sat, 6 Oct 2007 18:25:17 +0000 (11:25 -0700)
committerIra W. Snyder <devel@irasnyder.com>
Sat, 6 Oct 2007 18:25:17 +0000 (11:25 -0700)
This implements and adds the ElevatorController class to the project.

An ElevatorController manages a list of Elevators in a building, deciding
which ones to dispatch based on distance. It also can "step the simulation"
for all of the Elevators.

Signed-off-by: Ira W. Snyder <devel@irasnyder.com>
Makefile
elevatorcontroller.cpp [new file with mode: 0644]
elevatorcontroller.hpp [new file with mode: 0644]
test.cpp

index 8062d9a..116c3ce 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-test: position.o stop.o elevator.o test.o
+test: position.o stop.o elevator.o elevatorcontroller.o test.o
        g++ -o $@ $^
 
 run: test
diff --git a/elevatorcontroller.cpp b/elevatorcontroller.cpp
new file mode 100644 (file)
index 0000000..2baea64
--- /dev/null
@@ -0,0 +1,105 @@
+#include "elevatorcontroller.hpp"
+
+ElevatorController::ElevatorController (int floors, int elevators)
+       : number_of_floors_(floors)
+       , number_of_elevators_(elevators)
+       , elevators_()
+{
+       /* Seed the RNG */
+       std::srand ( std::time (NULL) );
+
+       /* Create and add all of the elevators */
+       for (int i=0; i<number_of_elevators_; i++)
+               elevators_.push_back (Elevator());
+}
+
+static int choose_random_number_in_range (int low, int high)
+{
+       return std::rand () % high + low;
+}
+
+void ElevatorController::call_elevator_to (int floor, Direction direction)
+{
+       std::cout << "Called elevator to: floor=" << floor << " direction=" << direction << std::endl;
+
+       /* Check the parameters */
+       if (floor < 0 || floor > number_of_floors_)
+               throw bad_floor ();
+
+       ElevatorList::iterator it;
+       std::vector<Elevator*> idle_elevators;
+       Stop requested_stop(floor, direction);
+
+       /* Find all idle Elevators */
+       for (it = elevators_.begin(); it != elevators_.end(); it++)
+               if (it->is_idle ())
+                       idle_elevators.push_back (&(*it));
+
+       if (idle_elevators.size() > 0)
+       {
+               int num = choose_random_number_in_range (0, idle_elevators.size());
+
+               idle_elevators.at (num) -> stop_at (requested_stop);
+               return;
+       }
+
+       /* Find the Elevator which is closest to the requested Stop */
+       bool found = false;
+       float distance = INT_MAX;
+       Elevator *e;
+
+       for (it = elevators_.begin(); it != elevators_.end(); it++)
+       {
+               if (it->distance_from (requested_stop) < distance)
+               {
+                       found = true;
+                       distance = it->distance_from (requested_stop);
+                       e = &(*it);
+               }
+       }
+
+       /* If we found one, send the closest Elevator */
+       if (found)
+       {
+               e->stop_at (requested_stop);
+               return;
+       }
+
+       /* Now we're having really bad luck. No elevators are idle, and none are closer than
+        * any other. A random choice will have to do. */
+       int num = choose_random_number_in_range (0, elevators_.size());
+       Elevator &e_ref = elevators_.at (num);
+
+       e_ref.stop_at (requested_stop);
+}
+
+void ElevatorController::elevator_request (int elevator_number, int floor)
+{
+       std::cout << "Request that elevator=" << elevator_number << " stop at floor=" << floor << std::endl;
+
+       /* Check the parameters */
+       if (elevator_number < 0 || elevator_number > number_of_elevators_)
+               throw bad_elevator ();
+
+       if (floor < 0 || floor > number_of_floors_)
+               throw bad_floor ();
+
+       /* Construct the Stop to use */
+       Stop s(floor, ALL);
+
+       /* Get the Elevator */
+       Elevator &e = elevators_.at (elevator_number);
+
+       /* Tell it where to stop */
+       e.stop_at (s);
+}
+
+void ElevatorController::move_elevators ()
+{
+       ElevatorList::iterator it;
+
+       for (it = elevators_.begin(); it != elevators_.end(); it++)
+               it->move();
+}
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
diff --git a/elevatorcontroller.hpp b/elevatorcontroller.hpp
new file mode 100644 (file)
index 0000000..75a5094
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * CS356 Project 01 -- Elevator Simulator
+ *
+ * ElevatorController Class Specification
+ */
+
+#ifndef ELEVATORCONTROLLER_HPP
+#define ELEVATORCONTROLLER_HPP
+
+#include "direction.hpp"
+#include "elevator.hpp"
+
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+#include <climits>
+#include <vector>
+
+typedef std::vector<Elevator> ElevatorList;
+
+/* Forward-declare Exceptions */
+class bad_elevator { };
+class bad_floor { };
+
+class ElevatorController
+{
+       public:
+               ElevatorController (int floors, int elevators);
+
+               void call_elevator_to (int floor, Direction direction);
+               void elevator_request (int elevator_number, int floor);
+               void move_elevators ();
+
+       private:
+               int number_of_floors_;
+               int number_of_elevators_;
+
+               ElevatorList elevators_;
+
+};
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
+
+#endif /* ELEVATORCONTROLLER_HPP */
index 54121a7..6f85ea1 100644 (file)
--- a/test.cpp
+++ b/test.cpp
@@ -6,10 +6,33 @@ using namespace std;
 #include "stop.hpp"
 #include "position.hpp"
 #include "elevator.hpp"
+#include "elevatorcontroller.hpp"
 
 
 int main (int argc, char *argv[])
 {
+       const int floors = 10;
+       const int elevators = 2;
+
+       ElevatorController ec(floors, elevators);
+
+       //ec.elevator_request (0, 2);
+       ec.call_elevator_to (3, DOWN);
+
+       for (int i=0; i<35; i++)
+               ec.move_elevators ();
+
+       // Note: without the GUI, this is dependent on choosing the same elevator
+       // that was randomly chosen by the call_elevator_to() funtion.
+       //
+       // This may need to be run a few times to work :)
+       ec.elevator_request (0, 2);
+
+       for (int i=0; i<35; i++)
+               ec.move_elevators ();
+
+
+#if TEST_ELEVATOR
        Elevator e(2);
 
        Stop s2(3, DOWN);
@@ -29,6 +52,7 @@ int main (int argc, char *argv[])
                usleep (500000);
                e.move ();
        }
+#endif
 
        return 0;
 }