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

📄 lift.c

📁 模拟电梯的运行过程
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <STDIO.H>   
#include <STDLIB.H>   
#include <ASSERT.H>   
//#include "lift.h"   
  
/* some global stats */  
int total_waiting = 0;  
int no_of_waits = 0;  
int max_wait = 0;  
int min_wait = 10000000;    
 int NO_OF_FLOORS=10  
  
/* 
 * Initialize the floors 
 */  
void init_floors(struct floor_s* floors)   
{  
  int i = 0;  
  for(i = 0; i < NO_OF_FLOORS; i++) {  
    floors[i].floor_number = i;  
    floors[i].num_waiting = 0;  
    floors[i].num_not_waiting = 0;  
  }  
}  
  
/* 
 * arrive_on_floor is called when a person arrives at a new floor. 
 */  
void arrive_on_floor(int time, struct floor_s* floor, struct person_s* person)  
{  
    person->target_floor = -1;  /* just arrived, don't want to go 
                   anywhere yet */  
    person->floor = floor->floor_number;  
  
    /* store them in the first free slot in the array */  
    floor->people_not_waiting[floor->num_not_waiting] = person;  
    floor->num_not_waiting++;  
  
    if (person->start_waiting != -1) {  
      total_waiting += time - person->start_waiting;  
      printf("Their journey time was %d\n", time - person->start_waiting);  
      if (time - person->start_waiting > max_wait) {  
    max_wait = time - person->start_waiting;  
      }  
      if (time - person->start_waiting < min_wait) {  
    min_wait = time - person->start_waiting;  
      }  
      no_of_waits++;  
      person->start_waiting = -1;  
    }  
}  
  
/*  
 * init_people initialized the people to start from the ground floor  
 */  
void init_people(struct floor_s* floors, struct person_s* people)   
{  
  int i = 0;  
  for(i = 0; i < NO_OF_PEOPLE; i++) {  
    people[i].name[0] = 'A' + i;  
    people[i].name[1] = '\0';  
    people[i].start_waiting = -1;  
    arrive_on_floor(0, &floors[0], &people[i]);  
  }  
}  
  
/*  
 * init_lists initializes the lifts to start from the ground floor 
 */  
void init_lifts(struct lift_s* lifts)  
{  
  int i;  
  for (i = 0; i < NO_OF_LIFTS; i++) {  
    lifts[i].lift_id = i;  
    lifts[i].occupants = 0;  
    lifts[i].position = 0;  
    lifts[i].speed = 0;  
    lifts[i].last_floor = 0;  
    lifts[i].mode = MODE_IDLE;  
  }  
}  
  
/* 
 * queue_for_list is called to add a person who was not previously 
 * queuing for a lift to the lift queue on their current floor 
 */  
void queue_for_lift(struct person_s* person, struct floor_s* floor)  
{  
  int i, j = -1;  
  
  /* find the person and remoove them from the pool of people not 
     queuing */  
  for (i = 0; i < floor->num_not_waiting; i++) {  
    if (floor->people_not_waiting[i] == person) {  
      for (j = i; j < floor->num_not_waiting-1; j++) {  
        
    floor->people_not_waiting[j] = floor->people_not_waiting[j+1];  
      }  
      break;  
    }  
  }  
  assert(j != -1);  
  floor->num_not_waiting--;  
  floor->people_not_waiting[floor->num_not_waiting] = NULL;  
  
  /* add them to the queue of people waiting for the lift */  
  floor->people_waiting[floor->num_waiting] = person;  
  floor->num_waiting++;  
}  
  
/* 
 * decide_action is called to allow a person to randomly decide if 
 * they want to go to another floor  
 */  
void decide_action(int time, struct person_s* person, struct floor_s* floor)  
{  
  if (person->target_floor != -1)   
    return;  /* they've already decided where they're going */  
  
  /* give then a 5% change of deciding to use the lift */  
  if (random()%100 > 95) {  
  
    /* choose a random floor (but not the one they're already on) */  
    person->target_floor = floor->floor_number;  
    while (person->target_floor == floor->floor_number) {  
      person->target_floor = random()%NO_OF_FLOORS;  
    }  
  
    /* add them to the queue */  
    queue_for_lift(person, floor);  
    printf("Person %s on floor %d decides to go to floor %d\n", person->name,  
       person->floor, person->target_floor);  
  
    /* the wait starts here */  
    person->start_waiting = time;  
    return;  
  }   
    
  /* otherwise do nothing */  
}  
  
/* 
 * person_enters_lift is called to move a person from a floor to a lift 
 */  
void person_enters_lift(int time, struct lift_s* lift, struct floor_s* floor) {  
  struct person_s * person;  
  int i;  
  assert(floor->num_waiting > 0);  
  
  person = floor->people_waiting[0];  
  /* shuffle everyone else up the queue */  
  for (i = 0; i < floor->num_waiting-1; i++) {  
    floor->people_waiting[i] = floor->people_waiting[i+1];  
  }  
  floor->num_waiting--;  
  floor->people_waiting[floor->num_waiting] = NULL;  
  
  printf("Person %s enters lift %d on floor %d\n",   
     person->name, lift->lift_id, floor->floor_number);  
  lift->people[lift->occupants] = person;  
  lift->occupants++;  
}  
  
/*  
 * people_enter_lift is called to move as many people as will fit from 
 * a floor queue to a lift 
 */  
void people_enter_lift(int time, struct lift_s* lift, struct floor_s* floor) {  
  while (floor->num_waiting > 0  
     && lift->occupants < MAX_PEOPLE_IN_LIFT) {  
    person_enters_lift(time, lift, floor);  
  }  
}  
  
/* 
 * person_leaves_lift is called to move a person from a lift to their 
 * target floor (when the lift is at that floor) 
 */  
void person_leaves_lift(int time, struct person_s* person,   
            struct floor_s* floor, struct lift_s* lift) {  
  printf("Person %s leaves lift %d on floor %d\n",   
     person->name, lift->lift_id, floor->floor_number);  
  arrive_on_floor(time, floor, person);  
}  
  
/* 
 * people_leave_lift is called to move people from a lift to their 
 * target floor (when the lift is at that floor) 
 */  
void people_leave_lift(int time, struct lift_s* lift, struct floor_s* floor) {  
  int i, j;  
  for (i = 0; i < lift->occupants; i++) {  
    while (lift->people[i]->target_floor == floor->floor_number) {  
      person_leaves_lift(time, lift->people[i], floor, lift);  
  
      /* shuffle everyone else up to fill the gap */  
      for (j = i; j < lift->occupants-1; j++) {  
    lift->people[j] = lift->people[j+1];  
      }  
      lift->occupants--;  
    }  
  }  
}  
  
/* 
 * distance_to_target calculates how far the lift still has to go to 
 * reach its target floor 
 */  
int distance_to_target(struct lift_s* lift)  
{  
  int target_position, dist;  
  target_position = lift->next_floor * FEET_PER_FLOOR;  
  dist = target_position - lift->position;  
  return abs(dist);  
}  
  
/* 
 * braking_distance calculates the distance a lift will take to stop 
 * if it tries to stop from the given speed 
 */  
int braking_distance(int speed)  
{  
  int dist = 0;  
  speed = abs(speed);  
  while(speed > 0) {  
    dist += speed;  
    speed--;  
  }  
  return dist;  
}  
  
  
/*  
 * speed_up is called to accelerate a lift 
 */  
void speed_up(struct lift_s* lift)  
{  
  if (lift->speed == 0) {  
    /* we weren't moving, so figure start in the right direction */  
    if (lift->next_floor * FEET_PER_FLOOR > lift->position)   
      lift->speed = 1;  
    else   
      lift->speed = -1;  
  } else if (lift->speed > 0) {  
    /* going up */  
    if (lift->speed < MAX_SPEED)  
      lift->speed++;  
  } else {  
    /* going down, so speed must become more negative */  
    if (abs(lift->speed) < MAX_SPEED)  
      lift->speed--;  
  }  
}  
  
/*  
 * slow_down is called to deccelerate a lift 

⌨️ 快捷键说明

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