
lafore_robert_objectoriented_programming_in_c
.pdf

666 |
Chapter 13 |
|
cin.get(ustring, BUF_LENGTH); |
//get floor |
|||
cin.ignore(10, |
‘\n’); |
//eat chars, |
including newline |
|
iFloor = atoi(ustring); |
//convert |
to |
integer |
|
cout << “Enter |
direction you want to |
go |
(u or d): “; |
|
cin.get(chDirection); |
//(avoid multiple linefeeds) |
|||
cin.ignore(10, |
‘\n’); |
//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(); |
|
} //end record_floor_reqs()
//-------------------------------------------------------------- |
|
//get_floor_req() -- |
see if there’s a specific request |
bool building::get_floor_req(const int dir, |
|
|
const int floor) const |
{ |
|
return floor_request[dir][floor]; |
|
} |
|
//-------------------------------------------------------------- |
|
//set_floor_req() -- |
set specific floor request |
void building::set_floor_req(const int dir, const int floor,
|
const bool updown) |
{ |
|
floor_request[dir][floor] = updown; |
|
} |
|
//-------------------------------------------------------------- |
|
//get_cars_floor() -- |
find where a car is |
int building::get_cars_floor(const int carNo) const |
|
{ |
|
return car_list[carNo]->get_floor(); |
|
} |
|
//-------------------------------------------------------------- |
|
//get_cars_dir() -- |
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
/////////////////////////////////////////////////////////////////


668 |
Chapter 13 |
|
switch(loading_timer) |
|
{ |
|
case 3: |
|
cout << “\x01\xDB \xDB “; |
//draw car with open door |
break; |
//happy face on left |
case 2: |
|
cout << “ \xDB\x01\xDB “; |
//happy face in open door |
get_destinations(); |
//get destinations |
break; |
|
case 1: |
|
cout << “ \xDB\xDB\xDB “; |
//draw with closed door |
break; |
//no happy face |
case 0: |
|
cout << “ \xDB\xDB\xDB “; |
//closed door, no |
break; |
//happy face (default) |
} |
|
set_cursor_pos(SPACING+(car_number+1)*SPACING, |
|
|
NUM_FLOORS-current_floor); |
switch(unloading_timer) |
|
{ |
|
case 3: |
|
cout << “\xDB\x01\xDB “; |
//draw car with open door |
break; |
//happy face in car |
case 2: |
|
cout << “\xDB \xDB\x01”; |
//draw car with open door |
break; |
//happy face on right |
case 1: |
|
cout << “\xDB\xDB\xDB “; |
//draw with closed door |
break; |
//no happy face |
case 0: |
|
cout << “\xDB\xDB\xDB “; |
//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 << ‘\xFE’; |
//small |
box |
else |
|
|
cout << ‘ ‘; |
//blank |
|
} |
|
|


Chapter 13
670
}
//if there’s a down floor request on this 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); |
||
if( !loading_timer) |
//load passengers |
|
loading_timer = LOAD_TIME; |
|
|
return; |
|
|
} |
|
|
//check if there are other destinations or requests |
||
//record distance to nearest request |
|
|
destins_above = destins_below = false; |
|
|
requests_above = requests_below = false; |
|
|
for(j=current_floor+1; j<NUM_FLOORS; j++) |
|
|
{ |
//check floors above |
|
if( destination[j] ) |
//if destinations |
|
destins_above = true; |
//set flag |
|
if( ptrBuilding->get_floor_req(UP, j) || |
|
|
ptrBuilding->get_floor_req(DN, j) ) |
|
|
{ |
//if requests |
|
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] ) |
//if destinations |
|
destins_below = true; |
//set flag |
|
if( ptrBuilding->get_floor_req(UP, j) || |
|
|
ptrBuilding->get_floor_req(DN, j) ) |
|
|
{ |
//if requests |
|
requests_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( !destins_above && !requests_above &&
!destins_below && !requests_below)
{


Chapter 13
672
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 requests above us if( (odir==DN || odir==STOP) && requests_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)
&& requests_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;
}//end decide(), finally
//-------------------------------------------------------------- |
|
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 |


Chapter 13
674
//elev_app.h
//provides constants to specify building characteristics
const |
int |
NUM_FLOORS |
= 20; |
//number |
of |
floors |
const |
int |
NUM_CARS = |
4; |
//number |
of |
elevator cars |
ELEV_APP.CPP initializes the data in the building class and creates a number of elevator objects, using new. (An array could also be used.) Then, in a loop, it calls the building functions master_tick() and get_floor_requests() over and over. The wait() function (declared in MSOFTCON.H or BORLACON.H) slows things down to a human-oriented speed. When the user is answering a prompt, time (the program’s time, as opposed to the user’s time) stops. Here’s the listing for ELEV_APP.CPP:
//elev_app.cpp
//client-supplied file
#include “elev.h” |
//for class declarations |
int main()
{
building theBuilding; while(true)
{
theBuilding.master_tick(); //send time tick to all cars wait(1000); //pause
//get floor requests from user theBuilding.record_floor_reqs();
}
return 0;
}
Elevator Strategy
Building the necessary intelligence into the elevator cars is not a simple task. It’s handled in the decide() function, which consists of a series of rules. These rules are arranged in order of priority. If any one applies, the appropriate action is carried out; the following rules are not queried. Here is a slightly simplified version:
1.If the elevator is about to crash into the bottom of the shaft, or through the roof, stop.
2.If this is a destination floor, unload the passengers.
3.If there is an up floor request on this floor, and we are going up, load the passengers.