Much Better Now
authorIra W. Snyder <devel@irasnyder.com>
Fri, 5 Oct 2007 01:10:23 +0000 (18:10 -0700)
committerIra W. Snyder <devel@irasnyder.com>
Fri, 5 Oct 2007 01:10:23 +0000 (18:10 -0700)
This was a major rewrite, but it seems to be working out more sanely now.

Signed-off-by: Ira W. Snyder <devel@irasnyder.com>
direction.hpp
elevator.cpp
elevator.hpp
position.cpp
position.hpp
stop.cpp
stop.hpp
test.cpp

index 927016b..b9863db 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef DIRECTION_HPP
 #define DIRECTION_HPP
 
-enum direction { IDLE, UP, DOWN, ALL };
+typedef enum { IDLE, UP, DOWN, ALL } Direction;
 
 #endif /* DIRECTION_HPP */
 
index 5543b02..3be175d 100644 (file)
 #include "elevator.hpp"
 
 Elevator::Elevator ()
-       : _stops()
-       , _pos()
-       , _direction(IDLE)
-       , _door_status(CLOSED)
+       : door_(CLOSED)
+       , direction_(IDLE)
+       , current_position_()
+       , stops_()
+       , ELEVATOR_STEP(0.1)
 {
        // Intentionally Left Empty
 }
 
-void Elevator::stop_at (int floor, enum direction _direction)
+bool Elevator::currently_at_stop () const
 {
-       std::cout << "Adding Stop: Floor=" << floor << " Dir=" << _direction << std::endl;
+       StopList::const_iterator it;
+       Stop current(current_position_, direction_);
 
-       _stops.push_back (Stop(floor, _direction));
+       for (it = stops_.begin (); it != stops_.end (); it++)
+               if (*it == current)
+                       return true;
+
+       return false;
+}
+
+void Elevator::stop_at (Stop &stop)
+{
+       StopList::iterator it;
+
+       /* If this is an "ALL" Stop, it supercedes all others */
+       if (stop.getDirection() == ALL)
+       {
+               stops_.remove (stop);
+               stops_.push_back (stop);
+               return;
+       }
+
+       /* Check if this stop already exists. If so, just leave */
+       for (it = stops_.begin(); it != stops_.end(); it++)
+               if (*it == stop)
+                       return;
+
+       /* The stop did not already exist, so add it */
+       stops_.push_back (stop);
+}
+
+float Elevator::distance_from (Position &pos) const
+{
+       if (current_position_ > pos)
+               return current_position_ - pos;
+
+       return pos - current_position_;
 }
 
-/*
- * Will check if direction needs to be changed, then change it.
- *
- * Will move this Elevator one step in the correct direction.
- *
- * The correct direction is defined based on the current direction:
- *
- * IDLE: Move in the direction that has the most stops
- *                     - Ex: if there are 10 stops above us, and two below, move DOWN
- *
- * UP: Move upwards
- *
- * DOWN: Move downwards
- */
 void Elevator::move ()
 {
-       /* Check if we are at a stop. If we are:
-        * 1) Open the doors
-        * 2) Clear the call button
+       static int wait = 0;
+
+       /* Wait around if we need to.
+        *
+        * This is an artificial delay to make the elevators work in a
+        * much more natural fashion. This allows some delay to leave the
+        * doors open, or for the user to press floor selection buttons
+        * before the elevator starts moving
         */
-       if (currently_at_stop ())
+       if (wait > 0)
        {
-               std::cout << "At a stop, right now" << std::endl;
+               --wait;
                return;
        }
 
-       /* Check if we have any more stops to attend to. If we do not, go IDLE */
-       if (_stops.size() == 0)
+       /* close the door if it is open. This is a requirement to move */
+       if (door_ != CLOSED)
        {
-               _direction = IDLE;
+               wait = 10;
+               close_door ();
                return;
        }
 
-       /* Find the best direction to move in, and set our direction to that */
-       if (_direction == IDLE)
-               _direction = find_best_direction ();
+       if (currently_at_stop ())
+       {
+               wait = 10;                                                                      // delay around for 10 steps
+               stops_.remove (Stop(current_position_, direction_));
+               open_door ();                                                           // call into the GUI to open the door
+               return;
+       }
+
+       /* Calculate the number of Stops above and below our
+        * current position */
+       StopList::const_iterator it;
+       Stop current = Stop(current_position_, direction_);
+       int stops_above = 0;
+       int stops_below = 0;
+
+       for (it = stops_.begin(); it != stops_.begin(); it++)
+       {
+               if (current < *it)
+                       ++stops_above;
+
+               if (current > *it)
+                       ++stops_below;
+       }
+
+       /* Check if we need to change direction */
+       if (direction_ == UP && stops_above == 0 && stops_below > 0)
+               direction_ = DOWN;
+
+       if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
+               direction_ = UP;
+
+       if (stops_above == 0 && stops_below == 0)
+               direction_ = IDLE;
+
 
-       /* Move */
-       switch (_direction)
+       /* Move in the correct direction */
+       switch (direction_)
        {
+               case IDLE:
+                       break;
                case UP:
-                       _pos += elevator_step;
+                       current_position_ += ELEVATOR_STEP;
                        break;
                case DOWN:
-                       _pos -= elevator_step;
+                       current_position_ -= ELEVATOR_STEP;
                        break;
                default:
-                       throw bad_direction ();
+                       std::cout << __FILE__ << ":" << __LINE__ << " Unhandled Elevator Position" << std::endl;
                        break;
        }
 
-       std::cout << "at position: " << _pos << std::endl;
+       /* Call the GUI with our updated position */
+       update_position ();
 }
 
-enum direction Elevator::find_best_direction ()
+bool Elevator::is_idle () const
 {
-       /* Make sure that the current direction is IDLE */
-       if (_direction != IDLE)
-               throw bad_direction();
-
-       std::vector<Stop>::const_iterator it;
-       int above, below;
-
-       /* Find out how many are above and below our current position */
-       for (above=0, below=0, it = _stops.begin(); it != _stops.end(); it++)
-       {
-               if (_pos < (*it))
-                       above++;
-
-               if (_pos > (*it))
-                       below++;
-       }
-
-       /* If we have nothing, then stay IDLE */
-       if (above == 0 && below == 0)
-               return IDLE;
-
-       /* If they are the same, always go up first.
-        *
-        * This comes from the design meeting on 2007-10-03 */
-       if (above == below)
-               return UP;
-
-       /* Otherwise, go in the direction that has the most stops */
-       return above > below ? UP : DOWN;
+       return direction_ == IDLE;
 }
 
-bool Elevator::currently_at_stop ()
+void Elevator::update_position () const
 {
-       std::vector<Stop>::iterator it;
-       Stop current (_pos, _direction);
+       std::cout << "Updating the GUI with our position" << std::endl;
+}
 
-       for (it = _stops.begin (); it != _stops.end (); it++)
-       {
-               std::cout << "cas(): current=" << current << " it=" << *it << std::endl;
-               if (*it == current)
-                       return true;
-       }
+void Elevator::open_door () const
+{
+       std::cout << "Opening Door" << std::endl;
+}
 
-       return false;
+void Elevator::close_door () const
+{
+       std::cout << "Closing Door" << std::endl;
 }
 
 
index cff6432..1b5c599 100644 (file)
@@ -8,85 +8,43 @@
 #define ELEVATOR_HPP
 
 #include <iostream>
-#include <vector>
-#include "position.hpp"
+#include <list>
 #include "direction.hpp"
+#include "position.hpp"
 #include "stop.hpp"
 
-
-enum door_status { CLOSED, OPEN };
-const float elevator_step = 0.1;
-
-class bad_direction { };
+typedef enum { CLOSED, OPEN } DoorStatus;
+typedef std::list<Stop> StopList;
 
 class Elevator
 {
        public:
-               /*
-                * PURPOSE: Construct a new Elevator object
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: A new Elevator will be constructed
-                */
                Elevator ();
 
-               /*
-                * PURPOSE: Tell the elevator to stop at the given floor,
-                * PURPOSE: going in the given direction.
-                *
-                * REQUIRE: floor is a valid floor
-                * REQUIRE: direction is either UP or DOWN
-                *
-                * PROMISE: The elevator will stop at the floor when it gets there
-                */
-               void stop_at (int floor, enum direction _direction);
-
-               /*
-                * PURPOSE: The elevator will move 1/10th of a floor in the current
-                * PURPOSE: direction.
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: The elevator will move if it has floors to stop at, otherwise
-                * PROMISE: it will sit idle at its current place.
-                */
+               void stop_at (Stop &stop);
+               float distance_from (Position& pos) const;
                void move ();
-
-       protected:
-               /*
-                * PURPOSE: Find the direction we should move in
-                *
-                * REQUIRE: _direction must be IDLE
-                *
-                * PROMISE: The best direction to move will be returned
-                */
-               enum direction find_best_direction ();
-
-               /*
-                * PURPOSE: Figure out if we are currently at a Stop in _stops
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: Return true if we are at a Stop in _stops, false otherwise
-                */
-               bool currently_at_stop ();
+               bool is_idle () const;
 
        private:
-               /* Storage for all of the places that we will be stopping */
-               std::vector<Stop> _stops;
+               /* Callbacks into the GUI */
+               void open_door () const;
+               void close_door () const;
+               void update_position () const;
 
-               /* Storage for the current elevator position */
-               Position _pos;
+               /* Analyze the list of stops */
+               bool currently_at_stop () const;
 
-               /* Stores the current direction */
-               enum direction _direction;
-
-               /* Stores the current door status */
-               enum door_status _door_status;
+               /* Elevator Status Variables */
+               DoorStatus      door_;
+               Direction       direction_;
+               Position        current_position_;
+               StopList        stops_;
 
+               const float     ELEVATOR_STEP;
 };
 
+
 #endif /* ELEVATOR_HPP */
 
 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */
index d38388b..f1cfc90 100644 (file)
@@ -1,28 +1,27 @@
 #include "position.hpp"
 
 Position::Position ()
-       : _major(0)
-       , _minor(0)
+       : major_(0)
+       , minor_(0)
 {
        // Intentionally Empty
 }
 
 Position::Position (int initial_position)
-       : _major(initial_position)
-       , _minor(0)
+       : major_(initial_position)
+       , minor_(0)
 {
        // Intentionally Empty
 }
 
-bool Position::operator== (const Position& rhs)
+bool Position::operator== (const Position& rhs) const
 {
-       return (_major == rhs._major) && (_minor == rhs._minor);
+       return (major_ == rhs.major_) && (minor_ == rhs.minor_);
 }
 
-
-bool Position::operator== (const int rhs)
+bool Position::operator!= (const Position& rhs) const
 {
-       return (_major == rhs) && (_minor == 0);
+       return ! (*this == rhs);
 }
 
 Position& Position::operator+= (const float rhs)
@@ -30,14 +29,14 @@ Position& Position::operator+= (const float rhs)
        int major = (int)rhs;
        int minor = (int)((rhs - major) * 10);
 
-       _major += major;
-       _minor += minor;
+       major_ += major;
+       minor_ += minor;
 
        /* Check for overflow */
-       if (_minor >= 10)
+       if (minor_ >= 10)
        {
-               _major += 1;
-               _minor -= 10;
+               major_ += 1;
+               minor_ -= 10;
        }
 
        return *this;
@@ -50,35 +49,64 @@ Position& Position::operator-= (const float rhs)
        return *this;
 }
 
-bool Position::operator< (const Position& rhs)
+bool Position::operator< (const Position& rhs) const
 {
-       if (_major < rhs._major)
+       if (major_ < rhs.major_)
                return true;
 
-       if (_major == rhs._major)
-               if (_minor < rhs._minor)
+       if (major_ == rhs.major_)
+               if (minor_ < rhs.minor_)
                        return true;
 
        return false;
 }
 
-bool Position::operator> (const Position& rhs)
+bool Position::operator> (const Position& rhs) const
 {
-       if (_major > rhs._major)
+       if (major_ > rhs.major_)
                return true;
 
-       if (_major == rhs._major)
-               if (_minor > rhs._minor)
+       if (major_ == rhs.major_)
+               if (minor_ > rhs.minor_)
                        return true;
 
        return false;
 }
 
-std::ostream& operator<< (std::ostream& os, Position& rhs)
+Position Position::operator- (const Position& rhs) const
 {
-       os << "Position: " << rhs._major << "." << rhs._minor;
-       return os;
+       Position temp;
+
+       int major = major_ - rhs.major_;
+       int minor = minor_ - rhs.minor_;
+
+       /* Check for underflow */
+       if (minor < 0)
+       {
+               minor += 10;
+               major -= 1;
+       }
+
+       temp.major_ = major;
+       temp.minor_ = minor;
+
+       return temp;
 }
 
+Position::operator float() const
+{
+       float temp;
+
+       temp = major_;
+       temp += minor_ / 10.0;
+
+       return temp;
+}
+
+std::ostream& operator<< (std::ostream& os, const Position& rhs)
+{
+       os << "Position(" << rhs.major_ << "." << rhs.minor_ << ")";
+       return os;
+}
 
 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */
index 02f4feb..0585b69 100644 (file)
 
 class Position
 {
+       friend std::ostream& operator<< (std::ostream& os, const Position& rhs);
+
        public:
-               /*
-                * PURPOSE: Construct a new Position object
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: A new Position object will be created, that
-                * PROMISE: starts at position 0.
-                */
                Position ();
-
-               /*
-                * PURPOSE: Construct a new Position object
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: A new Position object will be created, and will
-                * PROMISE: start at position initial_position
-                */
                Position (int initial_position);
 
-               /*
-                * PURPOSE: Compare two position objects
-                *
-                * REQUIRE: rhs is a valid Position object
-                *
-                * PROMISE: True if rhs is at the same position, false otherwise
-                */
-               bool operator== (const Position& rhs);
-
-               /*
-                * PURPOSE: Compare a Position and a float
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: True if rhs is within 0.05 of this Position
-                */
-               bool operator== (const int rhs);
-
-               /*
-                * PURPOSE: Add to this Position
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: This Position will have the rhs added to it
-                */
                Position& operator+= (const float rhs);
-
-               /*
-                * PURPOSE: Subtract from this Position
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: This Position will have the rhs added to it
-                */
                Position& operator-= (const float rhs);
 
-               bool operator< (const Position& rhs);
-               bool operator> (const Position& rhs);
-
-               friend std::ostream& operator<< (std::ostream& os, Position& rhs);
+               bool operator== (const Position& rhs) const;
+               bool operator!= (const Position& rhs) const;
+               bool operator< (const Position& rhs) const;
+               bool operator> (const Position& rhs) const;
+               Position operator- (const Position& rhs) const;
+               operator float() const;
 
-       protected:
-               int _major;
-               int _minor;
 
        private:
+               int major_;
+               int minor_;
 };
 
 #endif /* POSITION_HPP */
index ce491fc..620a6e1 100644 (file)
--- a/stop.cpp
+++ b/stop.cpp
@@ -1,28 +1,45 @@
 #include "stop.hpp"
 
-Stop::Stop (int floor, enum direction mydirection)
-       : Position(floor)
-       , _direction(mydirection)
+Stop::Stop (const Position& position, const Direction& direction)
+       : position_(position)
+       , direction_(direction)
 {
        // Intentionally Left Empty
 }
 
-Stop::Stop (Position pos, enum direction mydirection)
-       : Position (pos)
-       , _direction (mydirection)
+bool Stop::operator== (const Stop& rhs) const
 {
-       // Intentionally Left Empty
+       if (rhs.position_ != position_)
+               return false;
+
+       if (direction_ == ALL || rhs.direction_ == ALL)
+               return true;
+
+       return (rhs.direction_ == direction_);
+}
+
+bool Stop::operator< (const Stop& rhs) const
+{
+       /* If we do not use the direction to help differentiate, then it is
+        * possible that an object can be neither less, greater, or equal */
+       return ((position_ < rhs.position_) || (direction_ < rhs.direction_));
 }
 
-bool Stop::operator== (Stop& rhs)
+bool Stop::operator> (const Stop& rhs) const
 {
-       return (Position::operator==(rhs)) && (_direction == rhs._direction);
+       return (position_ > rhs.position_);
 }
 
-std::ostream& operator<< (std::ostream& os, Stop& rhs)
+const Direction Stop::getDirection () const
 {
-       os << "Stop: " << "help me" << " dir=" << rhs._direction;
+       return direction_;
+}
+
+std::ostream& operator<< (std::ostream& os, const Stop& rhs)
+{
+       os << "Stop(" << rhs.position_ << ", " << rhs.direction_ << ")";
        return os;
 }
 
+
 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */
index c7256bc..851c691 100644 (file)
--- a/stop.hpp
+++ b/stop.hpp
 #include "position.hpp"
 #include "direction.hpp"
 
-class Stop : public Position
+class Stop
 {
+       friend std::ostream& operator<< (std::ostream &os, const Stop& rhs);
+
        public:
-               /* PURPOSE: Construct a new Stop object, and set the floor and direction
-                *
-                * REQUIRE: Nothing
-                *
-                * PROMISE: A new Stop object will be created
-                */
-               Stop (int floor, enum direction mydirection);
-
-
-               Stop (Position pos, enum direction mydirection);
-
-               /*
-                * PURPOSE: Check if this and another Stop object is equivalent
-                *
-                * REQUIRE: rhs is a valid Stop object
-                *
-                * PROMISE: Return true if this and rhs are equivalent, false otherwise
-                */
-               bool operator== (Stop& rhs);
-               friend std::ostream& operator<< (std::ostream& os, Stop& rhs);
+               Stop (const Position& position, const Direction& direction);
 
-       private:
+               bool operator== (const Stop& rhs) const;
+               bool operator< (const Stop& rhs) const;
+               bool operator> (const Stop& rhs) const;
 
-               /* Storage for the direction */
-               enum direction _direction;
+               const Direction getDirection () const;
+
+       private:
+               Position        position_;
+               Direction       direction_;
 };
 
 #endif /* STOP_HPP */
index 9689cc1..a7e65d9 100644 (file)
--- a/test.cpp
+++ b/test.cpp
@@ -1,15 +1,18 @@
 #include <iostream>
+#include <list>
 using namespace std;
 
+#include "stop.hpp"
+#include "position.hpp"
 #include "elevator.hpp"
 
+
 int main (int argc, char *argv[])
 {
        Elevator e;
 
-       e.stop_at (1, DOWN);
-       e.stop_at (2, DOWN);
-       e.move ();
+       Stop s(1, UP);
+       e.stop_at (s);
        e.move ();
        e.move ();
        e.move ();
@@ -38,3 +41,4 @@ int main (int argc, char *argv[])
        return 0;
 }
 
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */