⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lift.c

📁 模拟电梯的运行过程
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 
 */  
void slow_down(struct lift_s* lift)  
{  
  if (lift->speed == 0)  
    /* can't slow down, we're already stopped */  
    return;  
  if (lift->speed > 0)  
    /* going up */  
    lift->speed--;  
  else  
    /* going down */  
    lift->speed++;  
}  
  
/*  
 * current_floor returns the number of the floor that a lift is stopped at 
 */  
int current_floor(struct lift_s* lift)  
{  
  assert(lift->position % FEET_PER_FLOOR == 0);  
  return lift->position/FEET_PER_FLOOR;  
}  
  
/* 
 * button_pressed returns TRUE if any lift button has been pressed on 
 * any floor. 
 */  
int button_pressed(struct floor_s* floors)   
{  
  int i;  
  for (i = 0; i < NO_OF_FLOORS; i++) {  
    if (floors[i].num_waiting > 0) {  
      printf("Button pressed: TRUE\n");  
      return TRUE;   
    }  
  }  
  /* printf("Button pressed: FALSE\n"); */  
  return FALSE;   
}  
  
/* 
 * decide_next_floor is called when the lift doors have closed, and a 
 * lift is about to depart.  It chooses the next floor the lift will 
 * stop at.  Essentially it is the lift scheduling algorithm, and so 
 * this determines the performance of the lift system 
 */  
int decide_next_floor(struct lift_s* lift, struct floor_s* floors)  
{  
  int closest_floor = -1, this_floor, i;  
    
  /* 
  int current_floor(struct lift_s* lift) 
{ 
  assert(lift->position % FEET_PER_FLOOR == 0); 
  return lift->position/FEET_PER_FLOOR; 
} 
*/  
  this_floor = current_floor(lift);  
  printf("Lift %d (on floor %d) is deciding the next floor\n",  
     lift->lift_id, this_floor);  
  
  /* is there anyone in the lift?  if so go where they want */  
  /* find the closest floor from those that the people in the lift 
     want to visit */  
  if (lift->occupants > 0) {  
    for (i = 0; i < lift->occupants; i++) {  
      printf("Passenger %s chose floor %d\n", lift->people[i]->name,  
        lift->people[i]->target_floor);  
      if (closest_floor == -1) {  
           /* first time through the loop */  
           closest_floor = lift->people[i]->target_floor;  
      } else if ( abs(lift->people[i]->target_floor - this_floor) <  
             abs(closest_floor - this_floor) ) {  
           /* this floor is closer than the previous closest */  
           closest_floor = lift->people[i]->target_floor;  
      }  
    }  
    printf("The closest chosen floor is %d\n", closest_floor);  
    assert(closest_floor != -1);  
    return closest_floor;  
  }  
  
  /* there's no-one in the lift, so we must choose from one of the 
     floors where people are waiting */  
  for (i = 0; i < NO_OF_FLOORS; i++) {  
    printf("There's no-one in the lift\n");  
    if (i == this_floor) continue; /* must move to a different floor */  
    if (floors[i].num_waiting > 0) {  
      printf("Button is pressed on floor %d\n", i);  
    }  
    if ( (floors[i].num_waiting > 0) &&  
     (abs(i - this_floor) < abs(closest_floor - this_floor)   
     || closest_floor == -1)) {  
      closest_floor = i;  
    }  
  }  
  
  /* if we haven't got an answer, don't move the lift */  
  if (closest_floor == -1)  
    closest_floor = this_floor;  
  else  
    printf("The closest chosen floor is %d\n", closest_floor);  
  return closest_floor;  
}  
  
  
/* 
 * move_lift implements the full lift state machine.  The doors open, 
 * then they stay open for a little while, during which people leave 
 * and enter the lift.  The doors close, then the lift decides when 
 * floor to visit next.  It accelerates, then it decelerates, stops, 
 * and the doors open again. 
 */  
void move_lift(int time, struct lift_s* lift, struct floor_s* floors)   
{  
  int distance_to_go;  
  
  switch(lift->mode) {  
  case MODE_OPENING:  
    if (lift->timer < DOOR_OPENING_DELAY) {  
      /* doors are opening, but not yet fully open */  
      lift->timer++;  
    } else {  
      /* doors are fully open */  
      lift->timer = 0;  
      lift->mode = MODE_OPEN;  
      printf("Lift %d, doors now open\n", lift->lift_id);  
    }  
    break;  
  case MODE_OPEN:  
    /* allow people in while there is space */  
    people_leave_lift(time, lift, &floors[current_floor(lift)]);  
    people_enter_lift(time, lift, &floors[current_floor(lift)]);  
  
    /* close the doors if the timer has expired */  
    if (lift->timer < DOOR_OPEN_DELAY) {  
      /* not yet time */  
      lift->timer++;  
    } else {  
      /* time to close the doors */  
      lift->timer = 0;  
      printf("Lift %d, doors starting to close\n", lift->lift_id);  
      lift->mode = MODE_CLOSING;  
    }  
    break;  
  case MODE_CLOSING:  
    /* model doors closing */  
    if (lift->timer < DOOR_CLOSING_DELAY) {  
      /* doors closing, but not yet closed */  
      lift->timer++;  
      break;  
    }  
  
    /* doors are closed, what happens next? */  
    printf("Lift %d, doors now closed\n", lift->lift_id);  
    lift->timer = 0;  
    if (lift->occupants == 0 && button_pressed(floors) == FALSE) {  
      /* there's nowhere to go, so just go idle */  
      lift->mode = MODE_IDLE;  
      lift->next_floor = -1;  
      printf("Lift %d Idle\n", lift->lift_id);  
    } else {  
      /* start the lift moving */  
      lift->next_floor = decide_next_floor(lift, floors);  
      lift->last_floor = current_floor(lift);  
      lift->mode = MODE_MOVING;  
      printf("Lift %d starting towards floor %d\n",   
         lift->lift_id, lift->next_floor);  
    }  
    break;  
  case MODE_MOVING:  
    /* lift is moving; control the speed to get there quickly without 
       overshooting */  
    lift->position += lift->speed;  
    printf("Lift %d moving, position: %d, speed %d\n",   
       lift->lift_id, lift->position, lift->speed);  
    distance_to_go = distance_to_target(lift);  
    if (distance_to_go == 0) {  
      lift->speed = 0;  
      lift->next_floor = -1;  
      lift->timer = 0;  
      lift->mode = MODE_OPENING;  
      printf("Lift %d arrived at position %d, doors opening\n",  
         lift->lift_id, lift->position);  
    } else if (distance_to_go >   
           (abs(lift->speed) + braking_distance(lift->speed))) {  
      /* speed up */  
      speed_up(lift);  
    } else if (distance_to_go >= braking_distance(lift->speed)){  
      /* this speed is OK */  
    } else {  
      /* slow_down */  
      slow_down(lift);  
    }  
    break;  
  case MODE_IDLE:  
    /* the lift is idle */  
    if (button_pressed(floors) == TRUE) {  
      /* someone called the lift */  
      lift->next_floor = decide_next_floor(lift, floors);  
      lift->mode = MODE_MOVING;  
      printf("Lift %d starting towards floor %d\n",   
         lift->lift_id, lift->next_floor);  
    }  
    break;  
  }  
}  
  
/* 
 * main loop, all the main paramaters are in lift.h 
 */  
  
int main(int arc, char **argv)   
{  
  int time;  
  struct floor_s floors[NO_OF_FLOORS];  
  struct person_s people[NO_OF_PEOPLE];  
  struct lift_s lifts[NO_OF_LIFTS];  
  
  init_floors(floors);  
  init_people(floors, people);  
  init_lifts(lifts);  
  
  srandom(0);  /* seed the random number generator so we always get 
          the same answer */  
  
  /* run the simulator for the prescribed time */  
  for (time = 0; time < MAX_TIME; time++) {  
    int i;  
    printf("t=%d\n", time);  
    for (i = 0; i < NO_OF_PEOPLE; i++) {  
      if (people[i].floor != -1) {  
    /* give each person a chance to decide what to do */  
    decide_action(time, &people[i], &floors[people[i].floor]);  
      } else {  
    /* they're in the lift, so they don't get a choice */  
      }  
    }  
    for (i = 0; i < NO_OF_LIFTS; i++) {  
      move_lift(time, &lifts[i], floors);  
    }  
  }  
  
  printf("-------------------------------------------------------------\n");  
  printf("Lift Statistics:\n");  
  printf("  Total waiting: %d\n", total_waiting);  
  printf("  No. of completed journeys: %d\n", no_of_waits);  
  printf("  Mean wait time: %f\n", (double)total_waiting / no_of_waits);  
  printf("  Min wait time: %d\n", min_wait);  
  printf("  Max wait time: %d\n", max_wait);  
       
  exit(0);  
}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -