电梯模拟系统

news/2025/2/2 2:55:48/

模拟九层电梯系统。有七个状态:正在开门(Opening)、已开门(opened)、正在关门(closing)、已关门(closed)、等待(waiting)、移动(moving)、减速(Decelerate)。

对于每个乘客有一个最长容忍时间,超过这个候电梯时间,他就会放弃。

模拟始终从0开始,时间单位为0.1s。人和电梯各种动作均要消耗一定时间单位(简记为t),比如:

有人进出时,电梯每隔40t测试一次,若无人进出,则关门。

关门开门各需要20t

每隔人进出电梯均需要25t

电梯加速需要15t

上升时,每一层需要51t,减速需要14t

下降时,每一层需要61t,减速需要23t

如果电梯在某层超过300t,则回一层待命

要求:按时序显示系统状态变化过程,即发生的全部人和电梯动作序列

扩展要求:实现电梯模拟可视化界面

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>#define GoingUp 1//匀速上升
#define GoingDown 2//匀速下降
#define SpeedUp 3//加速上升
#define SpeedDown 4//加速下降
#define SlowUp 5//减速上升准备停靠
#define SlowDown 6//减速下降准备停靠
#define Free 7//空闲
#define Stop 8//停止且已关门
#define DoorOpen 9//停止且门已打开
#define DoorOpening 10
#define DoorCloseing 11#define	CloseTest 40	//电梯关门测试时间
#define OverTime  300	//电梯停候超时时间
#define Accelerate 15	//加速时间
#define UpTime	51	//上升时间
#define DownTime 61	//下降时间
#define UpDecelerate 14  	//上升减速
#define DownDecelerate 23	//下降减速
#define DoorTime	20	//开门关门时间
#define InOutTime	25	//进出电梯时间#define MaxTime 10000  //最大容忍时间
#define MaxFloor 10   //最大层数9
#define BaseFloor 1//初始每层电梯等待队列和栈 
/*#define Init() ({int i;\for(i=0;i<MaxFloor;i++){\Stack[i].next=NULL;\Queue[i].next=NULL;\}\activity.next=NULL;\
})*/
typedef struct Person {int Id;           //numberint OutFloor;     //目标楼层int GiveupTime;   //容忍时间struct Person* next;
}Person;typedef struct Activity {int time;void(*fn)(void);struct Activity* next;
}Activity;typedef struct Person_Ele {int Id;struct Person_Ele* next;
}Person_Ele;int AddQueue(int floor, struct Person* p); //加入相应层的客户等待队列 
void AddAct(int time, void(*fn)(void));
void TestPeople();  //检查是否有客户放弃等待
void DoTime();
void Input(void);//电梯状态
void testinout(void);  //检测有无人进出 
void doclosedoor(void);  //电梯关门
void doopendoor(void);  //电梯开门
void doout(void); //出人
void doin(void); //进人
void doup(void); //上升
void dodown(void); //下降
void domove(void); //加速
void doslow(void); //停止
void tofirst();  //回一层
int GetWhere(void); //电梯行走方向int Time = 0;
int CallUp[MaxFloor] = { 0, };
int CallDown[MaxFloor] = { 0, };
int CallCar[MaxFloor] = { 0, };
int Floor = BaseFloor;
int State = Free;
int PersonId = 0;
Activity activity = { 0,NULL,NULL };
Person_Ele Stack[5] = { 0, };
Person Queue[5] = { 0, };int main() {//  Init();Input(); //输入用户信息DoTime();system("pause");return 0;
}int AddQueue(int floor, Person* p) {//加入相应层的客户等待队列 Person* tmp = &Queue[floor];//这始终加在链表的最后一位, while (tmp->next != NULL) {tmp = tmp->next;}tmp->next = p;return 0;
}void AddAct(int time, void(*fn)(void)) {//将一个活动加入定时器,时间到了调用这个函数 time = Time + time;					//这个函数参数必须是void,返回值也必须是voidstruct Activity* act;act = (struct Activity*)malloc(sizeof(struct Activity));act->next = NULL;act->fn = fn;act->time = time;struct Activity* p = &activity;while (p->next != NULL) {if (p->next->time>time)break;p = p->next;}act->next = p->next;p->next = act;
}void TestPeople() {//这是检测每层队列是否有人放弃,有人放弃就将他踢出队列 int i;      //每个时间都会被调用,效率相对较低 for (i = 0; i<MaxFloor; i++) {Person* p = Queue[i].next;Person* q = &Queue[i];if (p == NULL)continue;while (p != NULL) {if (p->GiveupTime <= Time) {if (Floor == i && (State >= Free))break;q->next = p->next;printf("User %d gave up and left   ——%d\n", p->Id,Time); //用户放弃等待,已离开free(p);p = q->next;continue;}q = p;p = p->next;}}
}int eexit = 0;  //退出参数
int people = 0;
void Input(void) {//输入人员信息,这个需要手动调用一次,之后就根据定时器调用了 Person* p = (Person*)malloc(sizeof(Person));int infloor, outfloor, giveuptime, intertime;while (1) {printf("\n*********************************************\n");printf("      ▲ 请输入用户%d起始楼层:",people++);scanf("%d", &infloor);printf("      ▲ 请输入用户%d目标楼层:", --people);scanf("%d", &outfloor);printf("      ▲ 请输入用户%d最长容忍时间:", people++);scanf("%d", &giveuptime);printf("      ▲ 请输入下一个用户的到来时间:");scanf("%d", &intertime);printf("      ▲ 退出--1,继续--2   ");scanf("%d", &eexit);if (eexit == 1)exit(0);  //退出函数printf("*********************************************\n\n");if (!(infloor<0 || infloor>MaxFloor - 1 || outfloor<0 || outfloor>MaxFloor - 1) && (infloor != outfloor))break;printf("录入错误请重输\n");}//giveuptime = OverTime;p->Id = PersonId++;p->GiveupTime = giveuptime + Time;p->next = NULL;p->OutFloor = outfloor;if (outfloor>infloor)CallUp[infloor] = 1;elseCallDown[infloor] = 1;AddQueue(infloor, p);AddAct(intertime, Input);
}void testinout(void) { //检测有无人进出 if (Queue[Floor].next || Stack[Floor].next)AddAct(CloseTest, testinout);else {State = DoorCloseing;CallUp[Floor] = 0;CallDown[Floor] = 0;CallCar[Floor] = 0;AddAct(DoorTime, doclosedoor);}
}void doclosedoor(void) //关闭电梯门
{  printf("door's closed   ——%d\n\n",Time);State = Stop;
}void doopendoor(void)  //打开电梯门 
{printf("\ndoor's opened   ——%d\n",Time);State = DoorOpen; //门打开了 AddAct(CloseTest, testinout);if (Stack[Floor].next)AddAct(InOutTime, doout);else { //没人出,就看有没有进的 if (Queue[Floor].next)AddAct(InOutTime, doin);}
}void doout(void) {//根据栈出人,如果没有看是否有人进 if (Stack[Floor].next) {Person_Ele* p = Stack[Floor].next;Stack[Floor].next = p->next;//;//显示信息 printf("User %d ------- get out of the elevator   ——%d\n", p->Id, Time); //出电梯free(p);}if (Stack[Floor].next) {AddAct(InOutTime, doout);}else {if (Queue[Floor].next)AddAct(InOutTime, doin);}
}void doin(void) {//人进入电梯,这里不用关电梯门它会定时关的 Person* p = Queue[Floor].next;if (p) {Queue[Floor].next = p->next;Person_Ele* pe = (Person_Ele*)malloc(sizeof(Person_Ele));int in = p->OutFloor;CallCar[in] = 1;//置位请求 pe->next = Stack[in].next;pe->Id = p->Id;Stack[in].next = pe;printf("User %d ------- get into the elevator   ——%d\n", p->Id,Time); //进电梯free(p);}if (Queue[Floor].next) {AddAct(InOutTime, doin);}
}int GetWhere(void) {static int old = 0;//保存上一次电梯的方向,保证电梯尽可能在一个方向走 int isup = 0, isdown = 0;int i;for (i = Floor + 1; i<MaxFloor; i++) {if (CallDown[i] || CallUp[i] || CallCar[i])isup = 1;}for (i = Floor - 1; i >= 0; i--) {if (CallDown[i] || CallUp[i] || CallCar[i])isdown = 1;}if (isup == 0 && isdown == 0) {return 0;}if (old == 0) {if (isdown) old = GoingDown;if (isup) old = GoingUp;return old;}if (old == GoingUp&&isup)return old;else if (old == GoingDown&&isdown)return old;else if (isdown)old = GoingDown;else if (isup)old = GoingUp;elseprintf("Error!\n"); //在选择方向时发生错误return old;
}void tofirst(void) {//回第一层if (State != Free || Floor == BaseFloor)return;printf("No one asked for a long time,ready to return to %d floor    ——%d\n", BaseFloor, --Time); Time--;//长时间没人请求电梯,将进入%d层CallCar[BaseFloor] = 2;//给电梯一个虚拟的去1层的请求,不会开门 
}void doslow(void) {//电梯停了 printf("Stop ------%d    ——%d\n", Floor,Time--);  //电梯停了,当前层是%dState = Stop;
}void doup(void) { //电梯上升Floor++;printf("going up --------%d    ——%d\n", Floor,Time);if (CallDown[Floor] || CallUp[Floor] || CallCar[Floor]) {State = SlowUp;AddAct(UpDecelerate, doslow);}else {if (Floor == MaxFloor - 1) {State = SlowUp;AddAct(UpDecelerate, doslow);}else {AddAct(UpTime, doup);}}
}void dodown(void) {  //电梯下降Floor--;printf("going down ------%d    ——%d\n", Floor,--Time);if (CallUp[Floor] || CallDown[Floor] || CallCar[Floor]) {State = SlowDown;AddAct(DownDecelerate, doslow);}else {if (Floor == 0) {State = SlowDown;AddAct(DownDecelerate, doslow);}else {AddAct(DownTime, dodown);}}
}void domove(void) {//加速完成,将进入正常速度 if (State == SpeedUp) {printf("Accelerating up    ——%d\n",--Time); //电梯加速上升State = GoingUp;AddAct(UpTime, doup);}else {printf("Accelerating Down    ——%d\n",--Time);  //电梯加速下降State = GoingDown;AddAct(DownTime, dodown);}
}void Controler(void) {if (State == Free || State == Stop) {if (CallUp[Floor] || CallDown[Floor] || CallCar[Floor]) {//当前层有请求,需要开门进出if (CallCar[BaseFloor] == 2) //在一楼{CallCar[BaseFloor] = 0;State = Free;printf("Nobody asked ------%d    ——%d\n", BaseFloor,Time--);  //现在在%d层,无人请求电梯return;}State = DoorOpening;AddAct(DoorTime, doopendoor);}else {//当前层无请求,判断其他层请求int whitch = GetWhere();if (whitch == GoingUp) {State = SpeedUp;AddAct(Accelerate, domove);}else if (whitch == GoingDown) {State = SpeedDown;AddAct(Accelerate, domove);}else {State = Free;if (Floor != BaseFloor)AddAct(OverTime, tofirst);}}}//否则电梯忙碌 return;
}void DoTime() {//此函数用于模拟时钟 while (1) {if (Time>MaxTime)return;TestPeople(); //两个始终都会被调用的函数 Controler();struct Activity* p = activity.next;if (p == NULL) {Time = MaxTime;}if (p&&Time >= p->time) {//取出活动队头的,检测定时是否到了 activity.next = p->next;p->fn();free(p);}Time++;}
}


http://www.ppmy.cn/news/500704.html

相关文章

基于 IoT + 5G技术搭建 10万台电梯智能化运维物联网平台

随着近20年我国房地产的蓬勃发展&#xff0c;电梯已经成为人们现代生活中不可或缺的一部分&#xff0c;也是城市化建设中重要的建筑设备之一。据中国电梯行业协会统计&#xff0c;截至2022年底&#xff0c;我国电梯保有量为990万台&#xff0c;电梯运营健康度&#xff0c;减少事…

智慧社区子场景之智慧电梯

社区、园区内电梯使用非常普遍&#xff0c;在智慧化建设中如何实现电梯的智能监管&#xff1f;电梯的故障告警、故障维修、保养计划、巡检计划又该怎样实现&#xff1f;物业在这个过程中可以怎样提高服务效率&#xff1f;对于热点问题电瓶车进入电梯事故可以怎样有效杜绝&#…

基于51单片机的简易电梯系统的设计

系统概述 设计要求 根据所学的知识以及技能&#xff0c;利用MCS-51系列单片机为中心设计一个简易电梯系统&#xff0c;实现四层电梯的无故障运行&#xff0c;并用数码管和指示灯显示对应楼层和运行方向等基本信息。设计所用的单片机为STC89C52为主要的控制器&#xff0c;自带A…

电梯运行控制模式:如何做到人脸识别、刷卡、二维码?

深圳市巨风科技有限公司专注人脸识别与人证核验研发生产&#xff0c;提供人脸识别场景应用解决方案&#xff0c;致力智慧城市建设智能化管理。公司围绕全场景智慧生活战略&#xff0c;打造精品和提升用户体验。公司完全自主研发的小门卫系列产品&#xff1a;人脸识别门禁机&…

FPGA实现简易电梯控制系统设计

这是某高校数字电路实验II课设&#xff0c;已实现2022年秋季学期所有功能 软硬件配置 系统&#xff1a;win10 软件&#xff1a;Vivado 2018.3 开发板芯片&#xff1a;xc7a35tftg256-2 设计要求 1、实现2层楼的简易电梯控制系统。 2、电梯有4个按键。 1楼外只有向上按键&…

实现电梯系统

用Java实现电梯系统 插入一段漂亮的代码片 标题如果输入的层数既有比当前楼层低又有比当前楼层高的话就进行先上升后下降&#xff0c;以下是运行的结果。 图片: 插入一段漂亮的代码片 import java.util.ArrayList; import java.util.Collections; import java.util.List; imp…

电梯模拟系统的实现

前言 电梯模拟系统是我大二数据结构的课设&#xff0c;当时花了5天的时间去完成&#xff0c;感谢某河师兄提供的支持。完成的效果个人觉得是很不错的&#xff0c;得到了数据结构老师的肯定&#xff0c;5天时间博美丽的数据结构老师一笑&#xff0c;想想也是值呀。 电梯系统实现…

基于机智云物联网平台的智能电梯管理系统

摘要: 随着科技的发展与电梯的普及&#xff0c;为解决传统电梯舒适性与安全性不足的问题&#xff0c;智能电梯管理系统解决方案应运而生。介绍了以STC89C52RC单片机为核心&#xff0c;使用数码管和LED、矩阵键盘、电机驱动、WiFi、语音播报、I/O口拓展、报警等模块组成的智能电…