Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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)&&current_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;
}