当前位置: 移动技术网 > IT编程>开发语言>C/C++ > 电梯模拟C++

电梯模拟C++

2018年04月09日  | 移动技术网IT编程  | 我要评论

蛋糕工坊4攻略,恋风,水银侠

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:存储乘客的相关信息,以便于在电梯模块中使用。

2struct node*类型的next,用于链接下一个节点。

 函数有:(1append(形参为乘客类数据):因为有头尾指针和头节点,只要把形参链接到尾部即可。

2empty:只要头指针指向的next为空就返回true,否则就返回false

3Remove(形参为乘客的ID):if当前节点是否就是所要删除的节点,如果是就根据是否是仅此一个节点或者是多个节点来分开处理;else当前节点不是要删除的节点,那么遍历整个链表去寻找所要删除的节点。

 

乘客类passenger

成员有:(1ID:用于设置乘客的编号。

2nowfloor:用于记录乘客当前楼层。

3gofloor:用于记录乘客需要去的楼层。

4whenwait:用于记录乘客多久进入等待队列。

函数有:(1)默认构造函数以及接口函数。

2setdata(参数为乘客ID):对该ID下的乘客进行赋值,并且限制乘客的当前楼层和所要前往的楼层为1-9,一旦超出范围则提示需要重新输入数据。

 

电梯类elevator

成员有:(1State:用于记录电梯的状态。

2floor:用于记录电梯所处楼层。

3Wait:指向等待队列头节点的指针。

4DiantiLI[10]:电梯里的人员数组,下标用于记录该层是否有人下电梯。

5All:记录电梯里的人数。

6Dir:用于判断电梯处于UpDown以外时之前所处的状态,以便于下一步的状态判断,-1为初始状态,0为下降,1为上升。

函数有:(1setnowState(参数为需要设定的电梯状态):用于更改电梯状态。

2setAll(参数为需要修改的乘客数量,有符号的整型):将参数与All参数进行加减。

(3)setDir(参数为想要把Dir改变的值):将Dir改变为参数值。

4JudgeGiveUp(参数为当前时间):用于判定当前是否有人放弃

如果(指针不为空){

如果(当前访问的节点的等待时间+忍耐时间==当前时间)

删除该节点并提示  }

(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{

     如果电梯里外都没有人{

         改变电梯状态并且返回空

}

         如果floor1{     //因为此时是电梯里外肯定至少有一种情况不为空

改变电梯状态为Up并且把Dir置为1

}

         如果floor9{

改变电梯状态为Down并且把Dir置为0

}

         如果电梯里有人{

            遍历数组DiantiLi得到下标i,并通过i来改变电梯状态

}

         如果电梯外不为空{

//此时根据电梯关门前的Dir来进行判定是否前往接乘客,此时分4种情况,2种上行,2种下行

如果Dir1{

如果乘客楼层在当前楼层之上,才有可能前往接乘客{

      如果该乘客是上行则将最远请求与该乘客的前往楼层对比,并进行更改

      否则如果乘客是下行,就将最远请求与该乘客的当前楼层对比,并进行对比

}

对最远请求进行对比和更改

}

如果Dir0{

  如果乘客楼层在当前楼层之下,才有可能前往接乘客{

      如果该乘客是下行则将最远请求与该乘客的前往楼层对比,并进行更改

      否则如果乘客是上行,就将最远请求与该乘客的当前楼层对比,并进行对比

}

对最远请求进行对比和更改

}

}

}

如果状态为Waiting{

  循环遍历等待队列,找出最先按键的人,去响应该请求

  如果ptemp(指向头节点)不为空{

如果便利到进入队列时间最早的乘客{

  如果是电梯需要上行

   则记录上行的最远请求

  如果是电梯需要下行

   则记录下行的最远请求

   如果两者皆有

   则满足先上后下的原则来改变电梯的状态

}

}

}

如果电梯状态为Up{

 如果电梯里有人{

遍历DiantiLi数组得到电梯里的乘客的最远请求

}

如果等待队列有人{

 遍历整个等待队列

 如果有乘客要去的楼层或者当前楼层比最远请求大

    则改变最远请求

}

}

如果电梯状态为Down{

 如果电梯里有人{

遍历DiantiLi数组得到电梯里的乘客的最远请求

}

如果等待队列有人{

 遍历整个等待队列

 如果有乘客要去的楼层或者当前楼层比最远请求小

    则改变最远请求

}

}

最后调用MoveDirction函数,并把最远请求传入

7MoveDirction(参数为最远请求):通过最远请求和目前的状态来调用不同的函数

    如果最远请求小于当前楼层

        调用MoveDown并返回空

    如果最远请求大于当前楼层

        调用MoveUp并返回空

    如果电梯状态目前为Opening

        调用Open函数并返回空

    如果电梯状态目前为In

        调用IN函数,并且调用JudgeClose函数进行判定此时是否还有人要进入,并返回空

    如果电梯状态目前为Out

         调用OUT函数,并且调用JudgeClose函数进行判定此时是否还有人要进入,返回空

   如果电梯状态目前为Opened

      JudgeClose判定是否关门

      调用JudgeOut判定是否有人要出门,如果有人出去,调用OUT;调用JudgeIn判定是否有人要进入,如果有人进入,调用IN,然后返回空

   如果电梯状态目前为Closing

      调用Close并返回空    

   如果最远请求等于当前楼层并且电梯里外都无人

      将电梯置为Waiting,并且进入NoPassenger输出电梯是空闲状态

   如果最远请求等于当前楼层且电梯里外是有人的

      此时将电梯置为Opening,并且进入Open   

8MoveDown:输出电梯下楼每一t的状态

     如果record(全局变量,用于输出电梯每一t的状态)小于枚举的值

       record自加,输出“电梯正在下楼”并返回空

     如果等于枚举的值时

       电梯的楼层自减1,并且record0

如果JudgeOpenfalse则继续调用MoveDown显示下楼的状态

            如果JudgeOpentrue则将电梯的状态置为Opening

(9)MoveUp:输出电梯上楼每一t的状态

    如果record(全局变量,用于输出电梯每一t的状态)小于枚举的值

       record自加,输出“电梯正在上楼”并返回空

     如果等于枚举的值时

       电梯的楼层自加1,并且record0

如果JudgeOpenfalse则继续调用MoveUp显示上楼的状态

            如果JudgeOpentrue则将电梯的状态置为Opening

10Open:显示电梯开门状态每一t的状态

      如果当前状态不为Opening

        设置当前状态为Opening,把record置为0,然后返回空

      如果record小于枚举的值

        record自加,输出“电梯开门中”,返回空

      如果是其他情况{

        record置为0,输出“开门完成”,将当前状态置为Opened

        如果JudgeOuttrue就调用OUT

        如果JudgeIntrue就调用IN

        JudgeClose判断是否关门

       }

11IN:显示哪些乘客进入电梯以及判定语句

      如果电梯里人少于13{

        如果record小于枚举值{

 如果当前状态为Opened{

record自加,遍历等待队列,并且加入判断乘客当前楼层必须是等于floor才能进入电梯

}

如果当前状态为In{

record自加,输出“乘客正在进入电梯”,返回空

}

}

如果是等于枚举值{

Record置为0,并且将当前状态置为Opened

}

}

如果电梯里的人数大于13{

输出“电梯内人数已经达到最大值”,将当前状态置为Closing

}

(12)JudgeClose:判断当前电梯是否可以关门

如果当前状态为Opened{

如果record小于枚举值{

record自加,输出“正在关门检测”,然后返回空

}

如果等于枚举值{

输出“关门检测结束”

如果当前状态为Opened{

record置为0,调用Close函数

}

否则 record置为0,并且返回空

}

}

其他情况返回空

      13Close:显示电梯关门时每一t的状态

            如果record小于枚举值{

 record自加,设置当前状态为Closing,输出“电梯正在关门中”

}

其他情况{

 record置为0,输出“电梯已经关门”,设置当前状态为Closed

 如果最大请求为floor{

 如果电梯里外有人{

 遍历整个等待队列

 如果此时等待队列有人发出请求

 如果停止前电梯是向上走的

则判断是否在当前楼层之上或者就是当前楼层,如果满足就设置当前状态为Opening

                 如果停止前电梯是向下走的

                  则判断是否在当前楼层之下或者就是当前楼层,如果满足就设置当前状态为Opening

}

如果电梯里外都没人

  设置当前状态为Waiting,把Dir置为-1

}

如果最大请求不是当前楼层{

 保持停止前电梯的状态不变

}

}

调用NoPassenger

14OUT:记录乘客下电梯的每一t的状态

        如果record小于枚举值{

如果当前状态为Opened{

          record自加

         如果电梯里有人要下电梯{

根据数组DiantiLi来判定下去多少个乘客并且输出下去时每一t状态,并且设置当前状态为Out,返回空

}

}

             如果当前状态为Out{

               record自加,输出“乘客正在下电梯”,返回空

             }

}

             其他情况则输出“需要下的乘客都已下去”,record置为0,并且把当前状态置为Opened

           }

15JudgeIn:判断是否可以进乘客

             如果All不为13{

                     如果等待队列不为空{

                         如果乘客是向上走的并且当前楼层在该层并且电梯之前的方向为向上

                            则允许进入,返回true

                        如果乘客是向下走的并且当前楼层在该层并且电梯之前的方向为向下

                           则允许进入,返回true

                             }

                      }

遍历完若没有返回true则此时返回false

16JudgeOut:判断乘客是否可以出去

       如果电梯里有人{

              数组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     

                    

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网