From: Ira W. Snyder Date: Fri, 5 Oct 2007 01:10:23 +0000 (-0700) Subject: Much Better Now X-Git-Url: https://irasnyder.com/gitweb/?a=commitdiff_plain;h=5c28697247e009e93b8b03bec8cdee88339d3226;p=cs356-p1-elevator.git Much Better Now This was a major rewrite, but it seems to be working out more sanely now. Signed-off-by: Ira W. Snyder --- diff --git a/direction.hpp b/direction.hpp index 927016b..b9863db 100644 --- a/direction.hpp +++ b/direction.hpp @@ -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 */ diff --git a/elevator.cpp b/elevator.cpp index 5543b02..3be175d 100644 --- a/elevator.cpp +++ b/elevator.cpp @@ -1,121 +1,154 @@ #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::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::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; } diff --git a/elevator.hpp b/elevator.hpp index cff6432..1b5c599 100644 --- a/elevator.hpp +++ b/elevator.hpp @@ -8,85 +8,43 @@ #define ELEVATOR_HPP #include -#include -#include "position.hpp" +#include #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 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 _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: */ diff --git a/position.cpp b/position.cpp index d38388b..f1cfc90 100644 --- a/position.cpp +++ b/position.cpp @@ -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: */ diff --git a/position.hpp b/position.hpp index 02f4feb..0585b69 100644 --- a/position.hpp +++ b/position.hpp @@ -11,73 +11,26 @@ 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 */ diff --git a/stop.cpp b/stop.cpp index ce491fc..620a6e1 100644 --- 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: */ diff --git a/stop.hpp b/stop.hpp index c7256bc..851c691 100644 --- a/stop.hpp +++ b/stop.hpp @@ -10,34 +10,22 @@ #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 */ diff --git a/test.cpp b/test.cpp index 9689cc1..a7e65d9 100644 --- a/test.cpp +++ b/test.cpp @@ -1,15 +1,18 @@ #include +#include 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: */