Project Description The goal of this project is to design and develop C ++ code
ID: 3839109 • Letter: P
Question
Project Description
The goal of this project is to design and develop C++ code and algorithms to control a bank of elevators, which services many floors and transports people “efficiently ", that is, as per the given specifications. A second goal is to effectively employ object oriented design, through appropriate use of classes, data structures and Standard Template Libraries (STLs).
Problem Specifications
• The elevator bank has m elevators and services n floors. As an example, you may choose m = 3 and n = 10.
• Each elevator can stop at every floor.
• The direction of an elevator has three states up, down and standing. Each elevator can carry up to a max of N max persons.
• The program loops through discrete time steps t = 1; 2…T stop, where T stop is an input parameter.
• At each time step, either 0, 1 or 2 persons arrive at a floor. This information can be read from an input data file, as described in 1.3.
•An elevator takes k time step to move up or down by k floors, if it doesn't stop. For example, to move from floor 4 to floor 5 requires one time step. And to move from floor 7 to floor 3 requires 4 time steps.
• When an elevator stops at a floor, for either passenger pick up or drop off, it does so for one time step.
•When a person arrives on a floor, they are assigned the “nearest "elevator. Here nearest is defined in the number of time steps. For example, let us say a person arrives on floor 5, and wants to go up. Elevator E1 on floor 2, moving in the up direction, with no stops, is 3 time steps away. Elevator E2 on floor 6, moving in the down direction and headed for floor 3 is 6 time steps away. Therefore, the person is assigned elevator E1.
• Each arriving person has an arrival floor, destination floor and the assigned elevator as its data members.
• When a person is assigned an elevator, their arrival floor and destination floor go in the queue or the list of the elevator stops.
• Each elevator contains a list of stops, which gets updated at each time step.
• An elevator moving up (down) continues to move up (down), until it exhausts all the stops in its list.
Class Design and STLs
You must make appropriate use of classes and class objects, class data members, class methods, constructors/destructors to implement your code.
Here are some suggested classes and their data members:
• Person class with ID, arrival floor, destination floor and assigned elevator. An example ID for a person maybe P1A3D5, for person 1, arrival floor 3 and destination floor 5. This will make it easier to generate and track test input and output.
• Elevator class with direction, number of people and list of stops.
Think of the STL containers you will be utilizing. For example, a list allows for easy insertion and removal of elements, a vector can change size, and you can push and pop elements at the end of it, a deque allows for fast insertion and deletion of elements at both ends.
Input Data
•The input data consists of the arrivals on each floor, at time steps t = 1. 2… T Stop. At each time step, the program reads in each arriving person, for each floor, and processes this data. For example, for n = 10 floors, and at time step t = 1, the arrivals maybe P1A1D4 and P2A1D5 on floor 1, P1A3D1 and Pf2A3D7 on floor 3, and 0 on the remaining floors.
Program Output
Generate appropriate output for a given input test data, which displays the information, that is, people getting on and off each floor, for each time step, for say 10 consecutive time steps.
Explanation / Answer
#include"elev_app.h"
#include"msoftcon.h" //for console graphics
#include<iostream.h>
#include<iomanip.h> //setw()
#include<conio.h>
#include<stdlib.h>
#include<process.h>
using namespace std;
enum direction {UP,DN,STOP};
const int LOAD_TIME= 3; //loading time
const int SPACING= 7; //visual spacing between cars
const int BUF_LENGTH= 80; //length of utility string buffer
class building; //forword decleration
class elevator
{
private:
building* ptrbuilding; Â Â
const int car_number;
int current_floor; Â Â
int old_floor; Â Â
direction current_dir; Â Â
bool destination[NUM_FLOORS];
int loading_timer; Â Â
int unloading_timer; Â Â
public:
elevator(building*,int);
void car_tick1(); Â Â
void car_tick2(); Â Â
void car_display(); Â Â
void dests_display()const;
void decide();
void move();
void get_destination(); Â Â
int get_floor()const; Â Â
direction get_direction()const;
};
class building
{
private:
elevator* car_list[NUM_CARS];
int num_cars;
bool floor_request[NUM_FLOORS];
public:
building();
-building(); Â Â
void master_tick();
int get_cars_floor(const int)const;
 Â
direction get_cars_dir(const int)const;
bool get_floor_req(const int,const int)const;
void set_floor_req(const int,const int,const bool);
void record_floor_req(); Â Â
void show_floor_req()const; Â Â
} ;
class building;
// function definitions for class building
building::building() Â Â
{
  char ustring[BUF_LENGTH];
  init_graphics();
  clear_screen();  Â
  num_cars=0;
  for(int k=0; k<num_cars; k++) //make elevetors
  {
     cars_list[k]=new elevator(this,num_cars);
     num_cars++;
  }
     for(int j=0; j<num_floors, j++)
     {set_cursor_pos(3, num_floors-j);
     itoa(j+1, ustring, 10);
     cout<< setw(3) <<ustring;
     floor_request[up][j]=false;
     floor_request[DN][j]=false;
     }
}
building::building() //destructor
{
  for(int k=0 k<num_cars;k++
     delete car_list[k];
}
void building:master_tick() //master time tick
{
  int j;
  show_floor_reqs(); //to display floor requests
  for(j=0; j<num_cars; j++) //for each elevator
     car_list[j]->car_tick1(); //send it time tick1
  for(j=00; j<num_cars; j++) //for each elevator
     car_list[j]->car_tick2(); //send it time tick 2
}
void building::show_floor_reqs() const
{
  for(int j=0; j<num_floors; j++)
  {
  set_cursor_pos(spacing, num_floors-j);
  if(floor_reqest[up][j]==true)
     cout<< '';  Â
  else
     cout<< ' ';
}
}
void building::record_floor_reqs()
{
  char ch='x';
  char ustring[BUF-LENGTH]; //utility string for input
  int ifloor; //floor for which request made
  char chDirection; //'u' or 'd' for up and down
  set_cursor_pos(1'22); //botton on the screen
     cout<< "press[enter] to call an elevator:";
  if(!kbhit()) //wait for keypress (must be CR)
     return;
  cin.ignore(10, ' ');
  if(ch=='') //if escape key; end program
     exit(0)
     set_cursor_pos(1,22); clear_line(); //clear old text
  set_cursor_pos(1,22); //botton of screen
  cout<<"enter the floor you're on:";
  cin.get(ustring,BUF_LENGTH); //get floor
  cin.ignore(10, ' '); //eat chars, including newline
  ifloor = atoi(ustring); //convert to integer
  cout<<"enter direction you want to go(u or d):";
  cin.get(chDirection); //void multiple linefeeds)
  cin.ignore(10, ' '); //eat chars; including newline
  if(chDirection=='u'|| chDirection=='u')
     floor_request[up][ifloor-1]=true; //up floor request
  if(chDirection=='d'||chDirection=='D')
     floor_request[DN][ifloor-1]=true; //down floor request
  set_cursor_pos(1,22); clear_line(); //clear old text
  set_cursor_pos(1,23); clear_line();
  set_cursor_pos(1,24); clear_line();
}
bool building::get_floor_req(const int dir,const int floor)const
{
  return floor_request[dir][floor];
}
//set specific floor request
void building::set_floor_req(const int dir,const int floor,const bool updown)
{
  return floor_request[dir][floor];
}
//find where a car is
int building::get_cars_floor(const int carNo) const
{
  return car_list[carNo]->get_floor();
}
//find which way car is going
direction building::get_cars_dir(const int carNO) const
{
  return car_list[carNo]->get_direction();
}
// function definitions for class elevator
elevator::elevator(building* ptrB,int nc):
ptrBuilding(ptrB),car_number(nc)
        {
           current_floor=0; //start at 0 (user's 1)
           old_floor=0; //remember previous floor
           current_dr=stop; //stationary at start
           for(int j=0; j<num_floors; j++) //occupants have not pushed
              destination[j]=false; //any buttons yet
           loading_timer =0; //not loading yet
unloading_timer = 0 //not unloading yet
        }
        int elevator::get_floor() const //get current floor
        {
           return current_floor;
        }
         Â
        direction elevator::get_direction() const //get current
        {
           return current_dir; //direction
        }
         Â
        void elevator::car_tick1()
        {
           car_display();
           dests_display();
           if(loading_timer)  Â
              --loading_timer;
           if(unloading_timer)  Â
              --unloading_timer;
           decide();  Â
        }
        void elevator::car_tick2()
        {
           move();  Â
        }
         Â
        void elevator::car_display()
        {
           set_cursor_pos(spacing+(car_number+1)*SPACING<NUM_FLOORS-old_floor);
           cout<<" "; //erase old position
           set_cursor_pos(SPACING-1+(car_number+1)*SPACING,NUM_FLOORS-current_floor);
           switch(loading_timer)
           {
case3:
              cout << "XDB"; //draw car with open door
              break; //happy face on left
case2:
              cout << "XBDÛ"; //happy face in open door
              get_destination(); //get destinations
              break;
case1:
              cout << "ÛÛ"; //draw with closed door
              break; //no happy face
case0:
              cout << "ÛÛÛ"; //closed door, no
              break; //happy face default
           }
           set_cursor_pos(spacing+(car_number+1)*SPACING,NUM_FLOOR-current_floor);
           switch(unloading_timer)
           {
case3:
              cout<<"ÛÛ"; //draw car with open door
              break; //happy face in the car
case2:
              cout<<"ÛÛ"; //draw car with open door
              break; //happy face on right
case1:
              cout<<"ÛÛÛ"; //draw with closed door
              break; //no happy face
case0:
              cout<<"ÛÛÛ"; //closed door,no
              break; //happy face(default
           }
           old_floor=current_floor; //remember old floor
        } //end car_display()
        //--------------------------------------------------------------------------------------------
        void elevator::dests_display() const //display destinations
        { //selected by buttons
           for(int j=0; j<NUM_FLOORS;j++) //inside the car
           {
              set_cursor_pos(SPACING-2+(car_number+1)*SPACING, NUM_FLOORS-j);
              if(destination[j] == true)
                 cout <<'þ'; //small box
              else
                 cout <<' ';
           }
        }
        void elevator::decide() //decide what to do
        {
           int j;
          Â
           bool destins_above,destins_below; //destinations
           bool request_above,request_below; //requests
          Â
           int nearest_higher_req=0;
           int nearest_lower_req=0
           bool car_between_up,car_between_dn;
           bool car_opposite_up,car_opposite_dn;
          Â
           int ofloor //floor
           direction odir; //direction
          Â
           if((current_floor==NUM_FLOOR-1 && current_dir==up)
              ||(current_floor==0 && current_dir==DN))
              current_dir=stop;
          Â
           if(destination[current_floor]==true)
           {
              destination[current_floor]=false; //erase destination
              if(!unloading_timer=load_time;
              return;
           }
           if(ptrBuilding->get_floor_req(up,current_floor)&¤t_dir!=DN))
        }
        current_dir=up;//(in case it was stop)
        //remove floor request for direction we're going
        ptrBuilding->set_floor_req(current_dir,current_floor,false); //load
        if(!loading_timer)
           loading_timer=load_time;
        return;
        }
        //if there's a down floor request on the floor,
        //and if we're going down or stopped, load passengers
        if(ptrBuilding->get_floor_req(DN,current_floor)&& current_dir!=up))
        {
           current_dir=DN; //(in case it was stop)
           //remove floor request for direction we're going
           ptrBuilding->set_floor_req(current_dir,current_floor,false); //load passenger
           if(!loading_timer)
              loading_timer=load_TIME;
           return;
        }
        //check if there are other destinations or requests
        //record distance to nearest request
        destins_above=destin_below=false;
        request_above=request_below=false;
        for(j=current_floor+1; j<NUM_FLOORS; j++)
        { //check floors above
           if(destination[j]) //if destinations
              destin_above=true; //set flag
           if(ptrBuilding->get_floor_req(up,j) //
              ptrBuilding->get_floor_req(DN,j)) //
           { //if request
              requests_above=true; //set flag
              if(!nearest_higher_req) //if not set before
                 nearest_higher_req=j; //set nearest req
           }
        }
        for(j=current_floor-1;j>=0;j--) //check floors below
        {
           if(destination[j]) //destinations
              destins_below=true; //set flag
           if(ptrBuilding->get_floor_req(up,j) //
              ptrBuilding->get_floor_req(DN,j))
           { //if request
              request_below=true //set flag
                 if(!nearest_lower_req) //if not set before
                    nearest_lower_req=j; //set nearest req
           }
        }
        //if no requests or destinations above or below,stop
        if(!destin_above && !request_above && !destins_below && !requests_below)
        {
           current_dir=stop
              return;
        }
        if(destins_above &&(current_dir==STOP||current_dir==up))
        {
           current_dir=up;
           return;
        }
        if(destins_below &&(current_dir=STOP||current_dir==DN))
        {
           current_dir=DN;
           return;
        }
        //find out if there are other cars,(a)going in the same
        //direction,between us and the nearest floor request;
        //or going the opposite direction,on the other
        //side of the floor request
        car_between_up=car_opposite_dn=false;
        car_oppoite_up=car_opposite_dn=false;
        for(j=0; j<NUM_CARS;j++) //check each car
        {
           if(j !=car_number) //if it's not us
           { //get it floor
              ofloor=ptrBuilding->get_cars_floor(j); //and
              odir=ptrBuilding->get_cars_dir(j); //direction
              //if it's going up and there are requests above us
              if(odir==up||odir==stop && requests_above)
                 //if it's above us and below the nearest request
              if(ofloor>current_floor && ofloor<==nearest_higher_req)
                    //or on same floor as us but is lower car number
                    ||(ofloor==current_floor && j < car_number))
                    car_between_dn=true;
              //if it's going up and there are request below us
              if((odir==up|| odir==stop) && requests_below)
                 //it's below request and closer to it than we are
                 if(nearest_lower_req >= ofloor&& nearest_lower_req - ofloor
                    <current_floor-nearest_lower_req)
                    car_opposite_up=true;
              //if it's going down and there are request above us
              if((odir==DN||odir==stop)&&request_above)
                 //it's above request and closer to it than we are
                 if(ofloor >=nearest_higher_req && ofloor-nearest_higher_req
                    <nearest_higher_req-current_floor)
                    car_opposite_dn=true;
           } //end if(not us)
        } //end for(each car)
        //if we're going up or stopped, and there is an FR above us,
        //and there are no other cars going up between us and the FR,
        //or above the FR going down and closer than we are,
        //then go up
        if((current_dir==up||current_dir==stop) && request_above && !car_between_up
           && !car_opposite_dn)
        {
           current_dir=up;
           return;
        }
        //if we're going down or stopped, and there is an FR below
        //us, and there are no other cars going down between us and
        //the FR, or below the FR going up and closer than we are ,
        //then go down
        if((current_dir==DN||current_dir==stop)
           && requests_below && !car_between_dn && !car_opposite_up)
        {
           current_dir=DN;
           return;
        }
        //if nothing else happening, stop
        current_dir=stop;
        }
        void elevator::move()
        { //if loading or unloading,
           if(loading_timer||unloading_timer) //don't move
              return;
           if(current_dir==up) //if going up,go up
              current_floor++;
           else if(current_dir==DN) //if going down,go down
              current_floor--;
        } //end move()
         Â
        void elevator::getdestinations() //stop, get destinations
        {
           char ustring[BUF_LENGTH]; //utility buffer for input
           int dest_floor; //destination floor
           set_cursor_pos(1,22);clear_line(); //clear top line
           set_cursor_pos(1,22);
           cout<<"car"<<(car_number+1)
              <<"has stopped at floor"<<(current_floor+1)
              <<" Enter destination floors(0when finished)";
           for(int j=1; j<NUM_FLOORS; j++) //get floor request
           { //maximum; usually fewer
              set_cursor_pos(1,24);
              cout<<"destination" <<j<<":";
              cin.get(ustring,BUF_LENGTH); //(avoid multiple LFS)
              cin.ignore(10,' ); //eat chars,including newline
                 dest_floor=atoi(ustring);
              set_cursor_pos(1,24);clear_line(); //clear old input line
              if(dest_floor==0) //if no more requests,
              { //clear botton three line
                 set_cursor_pos(1,22);clear_line();
              set_cursor_pos(1,23);clear_line();
              set_cursor_pos(1,24);clear_line();
              return;
              }
              --dest_floor; //start at 0;not1
              if(dest_floor==current_floor) //chose this very floor
              {--j;continue;}
              //if we're stopped,first choice made sets direction
              if(j==1 && current_dir==stop)
                 current_dir=(dest_floor<current_floor)? DN:UP;
              destination[dest_floor]=true; //record selection
              dests_display();
           }
        }
int main()
{
building thebuilding;
while(true)
thebuilding.master_tick(); //send time tick to all care
wait(1000); //pause
//get floor requests from user
thebuilding.record_floor_reqs();
}
return 0;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.