电梯模拟C++
1、问题描述与要求
模拟某校九层教学楼的电梯系统。该楼有一个自动电梯,能在每层停留,其中第一层是大楼的进出层,即是电梯的“本垒层”,电梯“空闲”时,将来到该层候命。
电梯一共有七个状态,即正在开门(Opening)、已开门(Opened)、正在关门(Closing)、已关门(Closed)、等待(Waiting)、移动(Moving)、减速(Decelerate)。
乘客可随机地进出于任何层。对每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。
模拟时钟从0开始,时间单位为0.1秒。人和电梯的各种动作均要消耗一定的时间单位(简记为t),比如:
有人进出时,电梯每隔40t测试一次,若无人进出,则关门;
关门和开门各需要20t;
每个人进出电梯均需要25t;
电梯加速需要15t;
上升时,每一层需要51t,减速需要14t;
下降时,每一层需要61t,减速需要23t;
如果电梯在某层静止时间超过300t,则驶回1层候命。
电梯调度规则:
1)就近原则:电梯的主要调度策略是首先响应沿当前行进方向上最近端的请求直到满足最远端请求。若该方向上无请求时,就改变移动方向;
2)在就近原则无法满足的情况下,首先满足更高层的请求;
3)电梯的最大承载人数为13人,电梯人数达到13人后,在有人出电梯之前,不接受进入电梯的请求;
4)乘客上下电梯时先出后进。进电梯时乘客是按发出乘坐请求的顺序依次进入,每次只能进入一人且每个人花费的时间都为25t;
5)电梯在关门期间(电梯离开之前)所在层提出请求的乘客同样允许进入。
要求:
按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。
扩展要求:
实现电梯模拟的可视化界面。用动画显示电梯的升降,人进出电梯。设计有下列对象:电梯、人、电梯控制板及其上各种按钮、定时器等。
2、设计
2.1 设计思想
数据由用户自定义输入,也可以进行改变使得通过用伪随机数方式来产生相关数据。此程序采用用户自定义输入,这种输入方式可以更加*化的决定相关数据,但是同样有弊端,不适合中途随意更改数据。操作的功能如下:添加乘客、是否有乘客请求、判断电梯方向、开关门的判断设计、乘客进出设计、电梯移动的判断设计、改变电梯状态、判断是否有人放弃来改变电梯的最远请求。主要的操作必须每次都遍历,所以时间会有点耗费过大,并且存储结构设计不大合理,导致每次都需要遍历所有数据,从而浪费时间。
存储结构采用电梯外的等待队列是单链表,电梯内部采用数组存储。等待队列的单链表设计为存储乘客类数据的结点,这样可以更加方便的访问乘客的相关信息,但是放弃了链表内部的排序,因为等待队列每次都需要遍历,所以排序会浪费更多的时间,因此抛弃该项功能。电梯内部的数组是开辟了10个大小,因为数组的下标是由0开始,所以为了更好地储存乘客前往的楼层,选择开辟10个大小的数组,每个下标里存储的数字代表着在该楼层下电梯的人数为多少人,选取数组存储的原因是一旦乘客进入电梯,有用的信息就仅仅只是下电梯的楼层,因此数组是一个较优解。
该程序中涉及最多的算法是穷举搜索法,该算法设计是为了每次都能够遍历所有的数据,但是该算法存在缺陷,无法应对很多数据的操作,因此限制了该程序的数据量。该算法使用for循环和while循环对数据进行遍历,并且在循环中插入判断语句,使得能够在得到需要的数据后进行一系列的操作。
2.2 设计表示
2.3 详细设计
链表结构体node中
成员有:(1)乘客类数据data:存储乘客的相关信息,以便于在电梯模块中使用。
(2)struct node*类型的next,用于链接下一个节点。
函数有:(1)append(形参为乘客类数据):因为有头尾指针和头节点,只要把形参链接到尾部即可。
(2)empty:只要头指针指向的next为空就返回true,否则就返回false。
(3)Remove(形参为乘客的ID):if当前节点是否就是所要删除的节点,如果是就根据是否是仅此一个节点或者是多个节点来分开处理;else当前节点不是要删除的节点,那么遍历整个链表去寻找所要删除的节点。
乘客类passenger中
成员有:(1)ID:用于设置乘客的编号。
(2)nowfloor:用于记录乘客当前楼层。
(3)gofloor:用于记录乘客需要去的楼层。
(4)whenwait:用于记录乘客多久进入等待队列。
函数有:(1)默认构造函数以及接口函数。
(2)setdata(参数为乘客ID):对该ID下的乘客进行赋值,并且限制乘客的当前楼层和所要前往的楼层为1-9,一旦超出范围则提示需要重新输入数据。
电梯类elevator中
成员有:(1)State:用于记录电梯的状态。
(2)floor:用于记录电梯所处楼层。
(3)Wait:指向等待队列头节点的指针。
(4)DiantiLI[10]:电梯里的人员数组,下标用于记录该层是否有人下电梯。
(5)All:记录电梯里的人数。
(6)Dir:用于判断电梯处于Up和Down以外时之前所处的状态,以便于下一步的状态判断,-1为初始状态,0为下降,1为上升。
函数有:(1)setnowState(参数为需要设定的电梯状态):用于更改电梯状态。
(2)setAll(参数为需要修改的乘客数量,有符号的整型):将参数与All参数进行加减。
(3)setDir(参数为想要把Dir改变的值):将Dir改变为参数值。
(4)JudgeGiveUp(参数为当前时间):用于判定当前是否有人放弃
如果(指针不为空){
如果(当前访问的节点的等待时间+忍耐时间==当前时间)
删除该节点并提示 }
(5)NoPassenger:主要是用于电梯处于闲置时的一些操作
如果电梯是Waiting状态{
如果holdtime(一个全局变量,用来检测是否达到300t)==300并且floor不等于1{
改变电梯状态为下降,并且把holdtime重新置0,进入MoveDown函数,返回true
}
如果holdtim==300并且floor等于1{
输出“电梯空闲无人”并把holdtime置为0,返回true
}
如果电梯里外都没有人{
输出“电梯空闲无人”,并且holdtime自加,返回true
}
其他情况就调用JudgeDirction函数,并且返回false
}
如果电梯不处于Waiting状态,调用JudgeDirction函数,并且返回false
(6)JudgeDirction:得出不同情况下的最远请求,传递给MoveDirction用于改变状态
如果状态为Closed{
如果电梯里外都没有人{
改变电梯状态并且返回空
}
如果floor为1{ //因为此时是电梯里外肯定至少有一种情况不为空
改变电梯状态为Up并且把Dir置为1
}
如果floor为9{
改变电梯状态为Down并且把Dir置为0
}
如果电梯里有人{
遍历数组DiantiLi得到下标i,并通过i来改变电梯状态
}
如果电梯外不为空{
//此时根据电梯关门前的Dir来进行判定是否前往接乘客,此时分4种情况,2种上行,2种下行
如果Dir为1{
如果乘客楼层在当前楼层之上,才有可能前往接乘客{
如果该乘客是上行则将最远请求与该乘客的前往楼层对比,并进行更改
否则如果乘客是下行,就将最远请求与该乘客的当前楼层对比,并进行对比
}
对最远请求进行对比和更改
}
如果Dir为0{
如果乘客楼层在当前楼层之下,才有可能前往接乘客{
如果该乘客是下行则将最远请求与该乘客的前往楼层对比,并进行更改
否则如果乘客是上行,就将最远请求与该乘客的当前楼层对比,并进行对比
}
对最远请求进行对比和更改
}
}
}
如果状态为Waiting{
循环遍历等待队列,找出最先按键的人,去响应该请求
如果ptemp(指向头节点)不为空{
如果便利到进入队列时间最早的乘客{
如果是电梯需要上行
则记录上行的最远请求
如果是电梯需要下行
则记录下行的最远请求
如果两者皆有
则满足先上后下的原则来改变电梯的状态
}
}
}
如果电梯状态为Up{
如果电梯里有人{
遍历DiantiLi数组得到电梯里的乘客的最远请求
}
如果等待队列有人{
遍历整个等待队列
如果有乘客要去的楼层或者当前楼层比最远请求大
则改变最远请求
}
}
如果电梯状态为Down{
如果电梯里有人{
遍历DiantiLi数组得到电梯里的乘客的最远请求
}
如果等待队列有人{
遍历整个等待队列
如果有乘客要去的楼层或者当前楼层比最远请求小
则改变最远请求
}
}
最后调用MoveDirction函数,并把最远请求传入
(7)MoveDirction(参数为最远请求):通过最远请求和目前的状态来调用不同的函数
如果最远请求小于当前楼层
调用MoveDown并返回空
如果最远请求大于当前楼层
调用MoveUp并返回空
如果电梯状态目前为Opening
调用Open函数并返回空
如果电梯状态目前为In
调用IN函数,并且调用JudgeClose函数进行判定此时是否还有人要进入,并返回空
如果电梯状态目前为Out
调用OUT函数,并且调用JudgeClose函数进行判定此时是否还有人要进入,返回空
如果电梯状态目前为Opened
JudgeClose判定是否关门
调用JudgeOut判定是否有人要出门,如果有人出去,调用OUT;调用JudgeIn判定是否有人要进入,如果有人进入,调用IN,然后返回空
如果电梯状态目前为Closing
调用Close并返回空
如果最远请求等于当前楼层并且电梯里外都无人
将电梯置为Waiting,并且进入NoPassenger输出电梯是空闲状态
如果最远请求等于当前楼层且电梯里外是有人的
此时将电梯置为Opening,并且进入Open
(8)MoveDown:输出电梯下楼每一t的状态
如果record(全局变量,用于输出电梯每一t的状态)小于枚举的值
record自加,输出“电梯正在下楼”并返回空
如果等于枚举的值时
电梯的楼层自减1,并且record置0
如果JudgeOpen为false则继续调用MoveDown显示下楼的状态
如果JudgeOpen为true则将电梯的状态置为Opening
(9)MoveUp:输出电梯上楼每一t的状态
如果record(全局变量,用于输出电梯每一t的状态)小于枚举的值
record自加,输出“电梯正在上楼”并返回空
如果等于枚举的值时
电梯的楼层自加1,并且record置0
如果JudgeOpen为false则继续调用MoveUp显示上楼的状态
如果JudgeOpen为true则将电梯的状态置为Opening
(10)Open:显示电梯开门状态每一t的状态
如果当前状态不为Opening
设置当前状态为Opening,把record置为0,然后返回空
如果record小于枚举的值
record自加,输出“电梯开门中”,返回空
如果是其他情况{
record置为0,输出“开门完成”,将当前状态置为Opened
如果JudgeOut为true就调用OUT
如果JudgeIn为true就调用IN
JudgeClose判断是否关门
}
(11)IN:显示哪些乘客进入电梯以及判定语句
如果电梯里人少于13人{
如果record小于枚举值{
如果当前状态为Opened{
record自加,遍历等待队列,并且加入判断乘客当前楼层必须是等于floor才能进入电梯
}
如果当前状态为In{
record自加,输出“乘客正在进入电梯”,返回空
}
}
如果是等于枚举值{
Record置为0,并且将当前状态置为Opened
}
}
如果电梯里的人数大于13{
输出“电梯内人数已经达到最大值”,将当前状态置为Closing
}
(12)JudgeClose:判断当前电梯是否可以关门
如果当前状态为Opened{
如果record小于枚举值{
record自加,输出“正在关门检测”,然后返回空
}
如果等于枚举值{
输出“关门检测结束”
如果当前状态为Opened{
record置为0,调用Close函数
}
否则 record置为0,并且返回空
}
}
其他情况返回空
(13)Close:显示电梯关门时每一t的状态
如果record小于枚举值{
record自加,设置当前状态为Closing,输出“电梯正在关门中”
}
其他情况{
record置为0,输出“电梯已经关门”,设置当前状态为Closed
如果最大请求为floor{
如果电梯里外有人{
遍历整个等待队列
如果此时等待队列有人发出请求
如果停止前电梯是向上走的
则判断是否在当前楼层之上或者就是当前楼层,如果满足就设置当前状态为Opening
如果停止前电梯是向下走的
则判断是否在当前楼层之下或者就是当前楼层,如果满足就设置当前状态为Opening
}
如果电梯里外都没人
设置当前状态为Waiting,把Dir置为-1
}
如果最大请求不是当前楼层{
保持停止前电梯的状态不变
}
}
调用NoPassenger
(14)OUT:记录乘客下电梯的每一t的状态
如果record小于枚举值{
如果当前状态为Opened{
record自加
如果电梯里有人要下电梯{
根据数组DiantiLi来判定下去多少个乘客并且输出下去时每一t状态,并且设置当前状态为Out,返回空
}
}
如果当前状态为Out{
record自加,输出“乘客正在下电梯”,返回空
}
}
其他情况则输出“需要下的乘客都已下去”,record置为0,并且把当前状态置为Opened
}
(15)JudgeIn:判断是否可以进乘客
如果All不为13{
如果等待队列不为空{
如果乘客是向上走的并且当前楼层在该层并且电梯之前的方向为向上
则允许进入,返回true
如果乘客是向下走的并且当前楼层在该层并且电梯之前的方向为向下
则允许进入,返回true
}
}
遍历完若没有返回true则此时返回false
(16)JudgeOut:判断乘客是否可以出去
如果电梯里有人{
数组DiantiLi中的该层楼的下标值中的数据不为0,则返回true
}
否则返回false
3、源程序清单
passenger.h //乘客类头文件,存放乘客的相关信息以及更改值的接口函数
elevator.h //电梯类头文件,存放枚举信息以及电梯的属性和相关判断函数
Node.h //节点类头文件,用于创建链表以及链表相关的操作函数
main.cpp //主函数,主要调用乘客类的设置属性函数,电梯类的JudgeGiveUp函数,以及电梯类的addpassenger函数,并且显示现在是多少t
4、源代码
passenger.h //乘客类头文件,存放乘客的相关信息以及更改值的接口函数
1 #ifndef PASSENGER_H 2 #define PASSENGER_H 3 #include<iostream> 4 using namespace std; 5 6 class passenger { 7 private: 8 int ID; 9 int nowfloor; 10 int gofloor; 11 int whenwait; 12 public: 13 passenger(); 14 void setdata(int ID1); 15 void setnowfloor(int nowfloor1); 16 void setgofloor(int gofloor1); 17 void setwhenwait(int whenwait1); 18 int getnowfloor()const; 19 int getgofloor()const; 20 int getID()const; 21 int getwhenwait()const; 22 }; 23 24 passenger::passenger() { 25 ID = 0; 26 nowfloor = 0; 27 gofloor = 0; 28 whenwait = 0; 29 } 30 31 void passenger::setdata(int ID1) { 32 ID = ID1; int i = 1; 33 while (i) { 34 cout << "请输入第" << ID << "位乘客的信息" << endl; 35 cout << "该乘客目前在哪一层:"; cin >> nowfloor; 36 cout << "该乘客去哪一层:"; cin >> gofloor; 37 cout << "该乘客何时上电梯:"; cin >> whenwait; 38 if (nowfloor > 9 || nowfloor < 0) { 39 cout << "乘客目前的楼层有误,请重输入!" << endl; 40 } 41 if (gofloor > 9 || gofloor < 0) { 42 cout << "乘客要去的楼层有误,请重输入!" << endl; 43 } 44 else i = 0; 45 } 46 } 47 48 void passenger::setnowfloor(int nowfloor1) { 49 nowfloor = nowfloor1; 50 } 51 52 void passenger::setgofloor(int gofloor1) { 53 gofloor = gofloor1; 54 } 55 56 void passenger::setwhenwait(int whenwait1) { 57 whenwait = whenwait1; 58 } 59 60 int passenger::getnowfloor()const { 61 return nowfloor; 62 } 63 64 int passenger::getgofloor()const { 65 return gofloor; 66 } 67 68 int passenger::getID()const { 69 return ID; 70 } 71 72 int passenger::getwhenwait()const { 73 return whenwait; 74 } 75 76 #endif // !PASSENGER_H 77 #pragma once
elevator.h //电梯类头文件,存放枚举信息以及电梯的属性和相关判断函数
1 #ifndef ELEVATOR_H 2 #define ELEVATOR_H 3 #include"Node.h" 4 #include"passenger.h" 5 6 enum state { 7 Opening, 8 Opened, 9 Closing, 10 Closed, 11 Waiting, 12 Up, 13 Down, 14 In, 15 Out, 16 Decelerate 17 }; 18 19 int holdtime = 0,record=0,near=0; 20 enum timeX 21 { 22 test = 40, 23 open = 20, 24 close = 20, 25 in = 25, 26 out = 25, 27 quick = 15, 28 up = 51, 29 updecelerate = 14, 30 down = 61, 31 downdecelerate = 23, 32 peoplewait = 500, 33 wait = 300 34 }; 35 36 class elevator { 37 private: 38 state State=Waiting; 39 int floor = 1; 40 PNODE Wait=p_head; 41 int DiantiLi[10] = {0}; 42 int All = 0; 43 int Dir=-1;//判断上下的情况 44 public: 45 state getnowState()const; 46 void setnowState(state t); 47 int getfloor()const; 48 void setfloor(int floor1); 49 int getAll()const; 50 void setAll(int num);//num为外部上电梯的人数 51 int getDir()const; 52 void setDir(int x); 53 void addpassenger(const passenger &x);//添加乘客 54 bool NoPassenger();//判断是否有乘客请求 55 void JudgeDirction();//判断电梯行走方向 56 bool JudgeOpen();//判断是否开门 57 void Open();//电梯门打开 58 bool JudgeOut();//判断乘客出去 59 void OUT();//乘客出去 60 bool JudgeIn();//判断乘客进入 61 void IN();//乘客进入 62 void Close();//关门 63 void MoveUp();//向上移动 64 void MoveDown();//向下移动 65 void JudgeClose();//40t时间来判断是否关门 66 void MoveDirction(const int floor1);//用来改变电梯的状态 67 void JudgeGiveUp(int waittime);//判断是否有人放弃,用在函数最开始 68 }; 69 70 state elevator::getnowState()const { 71 return State; 72 } 73 void elevator::setnowState(state t) { 74 State = t; 75 } 76 int elevator::getfloor()const { 77 return floor; 78 } 79 void elevator::setfloor(int floor1) { 80 floor = floor1; 81 } 82 int elevator::getAll()const { 83 return All; 84 } 85 void elevator::setAll(int num) { 86 All += num; 87 } 88 int elevator::getDir()const { 89 return Dir; 90 } 91 void elevator::setDir(int num) { 92 Dir = num; 93 } 94 void elevator::addpassenger(const passenger &x) { 95 append(x); 96 cout << " 第" << x.getID() << "名乘客进入等待队列 " ; 97 } 98 bool elevator::NoPassenger() { 99 //用于判断电梯是否接收乘客的请求 100 if (getnowState() == Waiting) { 101 if (holdtime == 300 &&floor!=1 ) { 102 //如果等够了300t并且不在1楼的话,开始下行 103 setnowState(Down); 104 setDir(0); 105 holdtime = 0; 106 MoveDown(); 107 return true; 108 } 109 else if (holdtime== 300 && floor == 1) { 110 //如果电梯本身在一楼则不需要进行操作 111 cout<< "电梯空闲无人,正在等待"; 112 holdtime = 0; 113 return true; 114 } 115 else if (All == 0 && empty()==true) { 116 cout << "电梯空闲无人,正在等待"; 117 holdtime++; 118 return true; 119 } 120 else { 121 JudgeDirction(); 122 return false; 123 } 124 } 125 else { 126 JudgeDirction(); 127 return false; 128 } 129 } 130 131 void elevator::JudgeDirction() { 132 //使用该函数进行判断电梯的走向 133 near = floor;//初始化near的值,为防止不满足条件的情况出现时依旧可以使用MoveDirction函数 134 int upoutfar = 0, downoutfar = 10;//定义2个记录上下出去最远请求的变量 135 int upinfar = 0, downinfar = 10;//定义2个记录上下进来最远请求的变量 136 if (State == Closed) { 137 if (getAll() == 0 && empty()==true) { 138 setnowState(Waiting); 139 return; 140 } 141 if (floor == 1) { 142 setnowState(Up); setDir(1); 143 } 144 if (floor == 9) { 145 setnowState(Down); setDir(0); 146 } 147 if (getAll() != 0) {//电梯里依旧有人 148 //此时需要区分电梯的运行方向,分两种情况来处理(目前还未处理) 149 for (int i = 1; i < 10; i++) { 150 if (DiantiLi[i] != 0) { 151 near = i; 152 if (i > floor) { 153 upinfar = i; 154 setnowState(Up); 155 setDir(1); 156 break; 157 } 158 else if (i < floor) { 159 downinfar = i; 160 setnowState(Down); 161 setDir(0); 162 break; 163 } 164 } 165 } 166 } 167 if (empty() == false) {//电梯外等待的人不为空 168 PNODE ptemp=p_head->next; 169 while (ptemp!=NULL) { 170 if (getDir() == 1) {//只接上行乘客 171 if (ptemp->data.getnowfloor() > floor) {//乘客所处楼层在电梯楼层上,这样才有可能电梯前往接人 172 //开始检索在链表中的乘客,并且进行判断是否有要上行的 173 if (ptemp->data.getgofloor() > ptemp->data.getnowfloor()) { 174 //代表此人是上行,并且是在电梯运行方向的楼上,需要前往接人 175 if (ptemp->data.getgofloor() > upoutfar)upoutfar = ptemp->data.getgofloor(); 176 } 177 if (ptemp->data.getgofloor() < ptemp->data.getnowfloor()) { 178 if (ptemp->data.getnowfloor() > upoutfar)upoutfar = ptemp->data.getnowfloor(); 179 } 180 } 181 if (upinfar == 0 && upoutfar == 0) { setnowState(Down); setDir(0); } 182 if (upinfar <= upoutfar)near = upoutfar; 183 else near = upinfar; 184 } 185 186 else if (getDir() == 0) {//只接下行乘客 187 if (ptemp->data.getnowfloor() < floor) {//乘客所处楼层在电梯楼层下,这样才有可能电梯前往接人 188 //开始检索在链表中的乘客,并且进行判断是否有要下行的 189 if (ptemp->data.getgofloor() < ptemp->data.getnowfloor()) { 190 //代表此人是下行,并且是在电梯运行方向的楼下,需要前往接人 191 if (ptemp->data.getgofloor() < downoutfar)downoutfar = ptemp->data.getgofloor(); 192 } 193 if (ptemp->data.getgofloor() > ptemp->data.getnowfloor()) { 194 if (ptemp->data.getnowfloor() < downoutfar)downoutfar = ptemp->data.getnowfloor(); 195 } 196 } 197 if (downinfar == 10 && downoutfar == 10) { setnowState(Up); setDir(1); } 198 if (downinfar <= downoutfar)near = downinfar; 199 else near = downoutfar; 200 } 201 ptemp = ptemp->next; 202 } 203 } 204 205 } 206 if (State == Waiting) { 207 PNODE ptemp = p_head->next; 208 int time_now = 0; 209 while (ptemp!=NULL) { 210 int Time_now = ptemp->data.getwhenwait();//用于记录最先按的人 211 time_now = Time_now; 212 if(ptemp->data.getwhenwait()<time_now){//挑选出最先按键的人,然后进行改变电梯的方向 213 time_now = ptemp->data.getwhenwait(); 214 } 215 ptemp = ptemp->next; 216 } 217 ptemp = p_head->next; 218 while (ptemp != NULL) { 219 int up(floor), down(floor); 220 if (ptemp->data.getwhenwait() == time_now) { 221 int x = ptemp->data.getgofloor() - ptemp->data.getnowfloor(); 222 //此时会出现4种情况,并且只会有2种是电梯上行,2种是电梯下行 223 if ((x > 0&& (ptemp->data.getnowfloor()>floor))||(x<0&& (ptemp->data.getnowfloor()>floor))) { 224 setnowState(Up); 225 setDir(1); 226 upinfar = ptemp->data.getnowfloor(); 227 if (up < upinfar) { 228 up = upinfar; 229 } 230 } 231 else if ((x > 0 && (ptemp->data.getnowfloor()<floor)) || (x<0 && (ptemp->data.getnowfloor()<floor))) { 232 setnowState(Down); 233 setDir(0); 234 downinfar = ptemp->data.getnowfloor(); 235 if (down > downinfar) { 236 down = downinfar; 237 } 238 } 239 if (down != floor&&up != floor) {//当上下同时有人请求时,满足先上的原则 240 setnowState(Up); near = upinfar; setDir(1); 241 } 242 else if (up != floor) {//只有上行的请求 243 setnowState(Up); near = upinfar; setDir(1); 244 } 245 else if (down != floor) {//只有下行的请求 246 setnowState(Down); near = downinfar; setDir(0); 247 } 248 if (floor == 1) { setnowState(Up); setDir(1); } 249 } 250 ptemp = ptemp->next; 251 } 252 if (near == floor) Open(); 253 } 254 if (State == Up) { 255 if (getAll()!=0) {//电梯里有人 256 for (int i = 1; i < 10; i++) { 257 if (DiantiLi[i] != 0) { 258 if (i >= near) { 259 upinfar = i; 260 } 261 } 262 } 263 } 264 if (empty() == false) { 265 PNODE ptemp = p_head->next; 266 while (ptemp != NULL) { 267 if (ptemp->data.getnowfloor() >= near) { 268 if (ptemp->data.getgofloor() >= upoutfar) { 269 upoutfar = ptemp->data.getgofloor(); 270 } 271 if (ptemp->data.getnowfloor() >= upoutfar) { 272 upoutfar = ptemp->data.getnowfloor(); 273 } 274 } 275 ptemp = ptemp->next; 276 } 277 } 278 if (upinfar >= upoutfar)near = upinfar; 279 else near = upoutfar; 280 } 281 if (State == Down) { 282 if (getAll() != 0) {//电梯里有人 283 for (int i = 1; i < 10; i++) { 284 if (DiantiLi[i] != 0) { 285 if (i <= near) { 286 downinfar = i; 287 break; 288 } 289 } 290 } 291 } 292 if (empty() == false) { 293 PNODE ptemp = p_head->next; 294 while (ptemp != NULL) { 295 if (ptemp->data.getnowfloor() <= near) { 296 if (ptemp->data.getnowfloor() <= downoutfar) { 297 downoutfar = ptemp->data.getnowfloor(); 298 } 299 if (ptemp->data.getgofloor() <= downoutfar) { 300 downoutfar = ptemp->data.getgofloor(); 301 } 302 } 303 ptemp = ptemp->next; 304 } 305 } 306 if (getAll() == 0 && empty() == true)near = 1; 307 else if (downinfar >= downoutfar)near = downoutfar; 308 else near = downinfar; 309 } 310 MoveDirction(near); 311 } 312 313 bool elevator::JudgeOpen() {//判断此楼层是否有人需要进出 314 if (JudgeIn() || JudgeOut()) { 315 Open(); 316 return true; 317 } 318 else return false; 319 } 320 321 void elevator::Open() { 322 if (getnowState() != Opening) { 323 setnowState(Opening); 324 record = 0; 325 return ; 326 } 327 if (record < open) { 328 record++; 329 cout << "电梯开门中"; 330 return; 331 } 332 else {//开门完成后 333 record = 0; 334 cout << "开门完成"; 335 setnowState(Opened); 336 if (JudgeOut())OUT(); 337 if (JudgeIn())IN(); 338 JudgeClose(); 339 } 340 } 341 342 bool elevator::JudgeOut() { 343 if (getAll() != 0) { 344 int j = floor; 345 if (DiantiLi[j] != 0)return true; 346 } 347 return false; 348 } 349 350 void elevator::OUT() { 351 if (record < out) { 352 if (getnowState() == Opened) { 353 record++; 354 cout << "乘客正在下电梯"; 355 if (DiantiLi[floor] != 0) { 356 cout << "在该层一共下去" << DiantiLi[floor] << "个人"; 357 setAll(-DiantiLi[floor]); 358 DiantiLi[floor] = 0; 359 } 360 setnowState(Out); 361 return; 362 } 363 if (getnowState() == Out) { 364 record++; 365 cout<< "乘客正在下电梯"; 366 return; 367 } 368 } 369 else { 370 cout << "电梯里需要下的乘客都已下去"; 371 record = 0; 372 setnowState(Opened); 373 } 374 } 375 376 bool elevator::JudgeIn() {//如果电梯未满,则返回true,可以继续进人 377 if (getAll() != 13) { 378 if (!empty()) {//不为空则执行if语句 379 PNODE ptemp = p_head->next; int upnum1=0,downnum1=0; 380 while (ptemp != NULL) { 381 if (ptemp->data.getnowfloor() == floor) { 382 if ((ptemp->data.getnowfloor() < ptemp->data.getgofloor()) && (getDir() > 0)) { 383 //乘客是往上走的 384 return true; 385 } 386 if ((ptemp->data.getnowfloor() > ptemp->data.getgofloor()) && (getDir() == 0)) { 387 //乘客下行 此处出现问题 388 return true; 389 } 390 if (near == ptemp->data.getnowfloor()) { 391 //达到了最大请求楼层,如果是与电梯方向同向,则不改变方向,并且允许进入 392 //如果不与电梯同向,则改变方向,如果两个情况都有,就优先满足同方向的 393 if (getDir() == 1) { 394 if (ptemp->data.getnowfloor() < ptemp->data.getgofloor()) { 395 setDir(1); upnum1++; 396 } 397 if (ptemp->data.getnowfloor() > ptemp->data.getgofloor()) { 398 setDir(0); downnum1++; 399 } 400 if (upnum1 != 0 && downnum1 != 0)setDir(1); 401 } 402 else if (getDir()==0) { 403 if (ptemp->data.getnowfloor() < ptemp->data.getgofloor()) { 404 setDir(1); upnum1++; 405 } 406 if (ptemp->data.getnowfloor() > ptemp->data.getgofloor()) { 407 setDir(0); downnum1++; 408 } 409 if (upnum1 != 0 && downnum1 != 0)setDir(0); 410 } 411 return true; 412 } 413 } 414 ptemp = ptemp->next; 415 } 416 } 417 } 418 return false; 419 } 420 421 void elevator::IN() { 422 if (getAll() < 13) { 423 if (record < in) 424 { 425 if (getnowState() == Opened) { 426 record++; 427 PNODE ptemp = p_head->next; 428 while (ptemp != NULL) { 429 if(ptemp->data.getnowfloor()==floor){//首先人得在电梯楼层,这才能进行判定 430 if ((ptemp->data.getnowfloor() < ptemp->data.getgofloor()) && (getDir() > 0)) { 431 //乘客是往上走的 432
相关文章:
-
-
题目链接 "简单的数学题" 题目描述 输入一个整数n和一个整数p,你需要求出 $$\sum_{i=1}^n\sum_{j=1}^n (i\cdot ... [阅读全文]
-
jquery ajax file upload NET MVC 无刷新文件上传
jquery ajax file upload NET MVC 无刷新文件上传 网上有各种各样的文件上传方法,有基于JS框架的、也有基于flash... [阅读全文] -
由于教程是围绕着文件打开做的错误处理,所以先记录几个用于文件处理的一些函数,fopen 用于打开一个文件;file_exists 用于检查目录是否存... [阅读全文]
-
1.修改tp5/application/index/controller/Index.php内容。 2.修改tp5/application/inde... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
下一篇: 使用Go语言解析动态JSON格式的方法
发表评论