📄 lift.c
字号:
#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 + -