/*
* elevator.c
*
* Created on: 2014年6月19日
* Author: LinBingcheng
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <time.h>
#include "elevator.h"
//////////////////////////////////////////////////////////////////////////
//
// 定义基本外部变量
//
//////////////////////////////////////////////////////////////////////////
int Start = 1; //本垒层
int Limit = 15; //电梯的限载
int Maxfloor = 4; //最高处
int Minfloor = 0; //最低层
float t = 0.1; //单位时间0.1毫秒
int CloseTime = 40; //电梯关门测试时间
int OverTime = 300; //电梯停候超时时间
int DoorTime = 20; //开门关门时间
int InOutTime = 25; //进出电梯时间
int AccelerteTime = 15; //加速时间
int UpTime = 51; //上升时间
int DownTime = 61; //下降时间
int UpDecelerateTime = 14; //上升减速
int DownDecelerateTime = 23; //下降减速
int InOutCount = 0; //用于进出计时
int InterTime = 0; //下一乘客进入系统的时间
//////////////////////////////////////////////////////////////////////////
//
// 函数实现
//
//////////////////////////////////////////////////////////////////////////
Client *InitClient() {
Client *C = (Client*) malloc(C_LEN);
C->statu = New;
if (!C) {
exit(OVERFLOW);
}
return C;
}
Status DestroyClient(Client *C) {
free(C);
return OK;
}
void PrintClient(Client *C) {
switch (C->statu) {
case New:
printf("%d号乘客进入第%d号电梯第%d层:目标层为第%d层,进入时间为 %.1f S,忍耐时间为 %.1f S\n",
C->id, C->e_id, C->InFloor, C->OutFloor, C->InterTime * t,
C->GiveupTime * t);
break;
case GiveUp:
printf("\t第 %.1f S 时\t%d号乘客放弃等待第%d号电梯\n",
(C->InterTime + C->GiveupTime) * t, C->id, C->e_id);
break;
case Out:
printf("\t%d号乘客走出第%d号电梯\n", C->id, C->e_id);
break;
case In:
printf("\t%d号乘客走进第%d号电梯,要去第%d层\n", C->id, C->e_id, C->OutFloor);
break;
default:
break;
};
}
LinkQueue *InitQueue() {
LinkQueue *Q = (LinkQueue *) malloc(C_Q_LEN);
if (!Q) {
exit(OVERFLOW);
}
Q->front = Q->rear = (QNode *) malloc(sizeof(QNode));
if (!Q->front) {
exit(OVERFLOW);
}
Q->front->next = NULL;
Q->front->data = NULL;
return Q;
}
Status ClearQueue(LinkQueue *Q) {
while (Q->front) {
Q->rear = Q->front->next;
if (Q->front->data) {
free(Q->front->data);
free(Q->front);
} else {
break;
}
Q->front = Q->rear;
}
return OK;
}
Status DestroyQueue(LinkQueue *Q) {
while (Q->front) {
Q->rear = Q->front->next;
if (Q->front->data) {
free(Q->front->data);
free(Q->front);
} else {
break;
}
Q->front = Q->rear;
}
free(Q);
return OK;
}
int QueueLength(LinkQueue *Q) {
QNode *qn;
int length = 0;
for (qn = Q->front; qn != Q->rear; qn = qn->next) {
length++;
}
return length;
}
QueuePtr GetHead(LinkQueue *Q) {
if (Q->front == Q->rear) {
return NULL;
}
return Q->front->next;
}
Status EnQueue(LinkQueue *Q, QElemType e) {
QNode *p;
p = (QNode *) malloc(sizeof(QNode));
if (!p) {
exit(OVERFLOW);
}
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
Status DeQueue(LinkQueue *Q, QElemType e) {
QueuePtr p;
if (Q->front == Q->rear)
return ERROR;
p = Q->front->next;
e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
free(p);
return OK;
}
Boolean QueueEmpty(LinkQueue Q) {
if (Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
Status QDelNode(LinkQueue *Q, QueuePtr p) {
QueuePtr q;
if (p == NULL || p->next == NULL)
return ERROR;
q = GetHead(Q);
while (q) {
if (q->data->id == p->data->id) {
if (q == GetHead(Q)) {
Q->front->next = q->next;
break;
}
q->next = q->next->next;
break;
}
q = q->next;
}
return OK;
}
Status CGiveUp(LinkQueue *Q, int floor, int nowTime) {
QueuePtr p;
p = Q->front;
if (p->next != NULL) {
if (p->next->data->GiveupTime == 0 && floor != p->next->data->InFloor
&& p->next->data->statu == New) {
p->next->data->statu = GiveUp;
printf("\t***********\n");
PrintClient(p->next->data);
}
if (nowTime >= p->next->data->InterTime) {
--p->next->data->GiveupTime;
}
}
return OK;
}
void PrintQueue(LinkQueue Q) {
QueuePtr q;
q = Q.front->next;
while (q != NULL) {
PrintClient(q->data);
q = q->next;
}
}
Elevator *InitElevator() {
int i = 0;
Elevator *E = (Elevator *) malloc(E_LEN);
if (!E) {
exit(OVERFLOW);
}
for (i = 0; i < 2; i++) {
E->queue[i] = InitQueue();
}
E->floor = Start;
E->toFloor = Start;
E->length = 0;
E->maxSize = Limit;
E->statu = Idle;
E->nowStatu = Waiting;
E->CountTime = 0; //用于开关门计时
for (i = 0; i < Size; i++) {
E->CallCar[i] = FALSE;
}
return E;
}
Status DestoryElevator(Elevator *E) {
int i;
for (i = 0; i < 2; i++) {
DestroyQueue(E->queue[i]);
}
free(E);
return OK;
}
void PrintElevator(Elevator *E, int NowTime) {
printf("\t第 %.1lf S 时\t第 %d 号电梯抵达第 %d 层\t", NowTime * t, E->id, E->floor);
if (E->statu == GoingDown) {
printf("方向向下\n");
}
if (E->statu == GoingUp) {
printf("方向向上\n");
}
if (E->statu == Idle) {
printf("在此层等候\n");
}
}
Boolean Call(Elevator *E, int NowTime) {
Boolean flag = FALSE; //有人呼叫电梯
QueuePtr p, q;
p = GetHead(E->queue[0]);
q = GetHead(E->queue[1]);
while (p) {
if (NowTime == p->data->InterTime) {
E->CallCar[p->data->InFloor - Minfloor] = TRUE;
printf("\t第%0.1fS\t", NowTime * t);
{
QueuePtr q;
q = E->queue[0]->front->next;
while (q != NULL) {
if (NowTime == q->data->InterTime) {
printf("%d号乘客在第%d号电梯第%d层\t", q->data->id, q->data->e_id,
q->data->InFloor);
flag = TRUE;
}
q = q->next;
}
}
printf("呼叫电梯\n");
}
p = p->next;
}
while (q) {
if (NowTime == q->data->InterTime) {
E->CallCar[q->data->InFloor - Minfloor] = TRUE;
printf("\t第%0.1fS\t", NowTime * t);
{
QueuePtr q;
q = E->queue[1]->front->next;
while (q != NULL) {
if (NowTime == q->data->InterTime) {
printf("%d号乘客在第%d号电梯第%d层\t", q->data->id, q->data->e_id,
q->data->InFloor);
flag = TRUE;
}
q = q->next;
}
}
printf("呼叫电梯\n");
}
q = q->next;
}
return flag;
}
int InOut(Elevator *E, int NowTime) {
int sum = 0; //进出队列总人数
ClientQueue *qu;
QueuePtr p, q;
qu = E->queue[0];
//乘客出电梯
p = GetHead(E->queue[0]);
while (p) {
if (p->data->OutFloor == E->floor && p->data->statu == In) {//判断乘客是否在电梯内并且应在此层出去
p->data->statu = Out; //状态改为出电梯
PrintClient(p->data);
--E->length; //乘客数减一
++sum;
}
q = p->next;
p = q;
};
qu = E->queue[1];
p = GetHead(E->queue[1]);
while (p) {
if (p->data->OutFloor == E->floor && p->data->statu == In) {//判断乘客是否在电梯内并且应在此层出去
p->data->statu = Out; //状态改为出电梯
PrintClient(p->data);
--E->length; //乘客数减一
++sum;
}
q = p->next;
p = q;
};
//乘客入电梯
qu = E->queue[0];
p = GetHead(E->queue[0]);
while (p) {
if (E->length == E->maxSize) { //判断是否满载
printf("第%d号电梯已满载,请乘客耐心等待\n", E->id);
break;
}
if (p->data->InFloor == E->floor && p->data->statu == New
&& p->data->InterTime < NowTime) { //在乘客出电梯这段时间进入系统的乘客都可以进电梯
p->data->statu = In;
PrintClient(p->data);
++E->length; //乘客数加一
E->CallCar[p->data->OutFloor - Minfloor] = TRUE;
++sum;
}
q = p->next;
p = q;
};
qu = E->queue[1];
p = GetHead(E->queue[1]);
while (p) {
if (E->length == E->maxSize) { //判断是否满载
printf("第%d号电梯已满载,请乘客耐心等待\n", E->id);
break;
}
if (p->data->InFloor == E->floor && p->