电梯调度系统(界面由C图形库编绘)

电梯调度系统编程

1、编程题目

     电梯调度。

 

2、结对编程组员

     黄冠译,刘畅。

 

3、编程语言

     C语言图形库。

 

4、题目要求:

 

5、代码运行及结果调试:

① 运行界面为C++图形库支持,开始运行的初始界面如图,且默认所有电梯初始状态都为1楼,此时不分奇偶层:

② 我设置了鼠标响应事件,左边上下箭头为当前楼层有人要上或下的按钮,可以用鼠标直接点击响应,点击后要输入有多少人在此楼层等待,示例点击5楼,输入15人,如图所示:

③ 输入完毕后,电梯会根据单双层或全部楼层4个电梯的忙碌状态调度一个电梯过去,第一个调度1号电梯,因为1号电梯只能容纳10人,剩余5人还在等待,此时会再调度另一个电     梯过去接人,优先调度全部楼层的,所以调度4号电梯,如图所示:

④ 当两个电梯都接完人后,右侧电梯状态的1号和4号显示如图,1号10人,满状态,4号5人:

⑤ 1号和4号电梯此时可以点击右侧电梯内部按钮,若有人在电梯内才可以点击,否则无法点击,我们对1号电梯选择12楼,此时会出现输入12楼下电梯的人数,我们输入4人,电       梯就会到12楼去送人,如图所示:

⑥ 1号电梯送完人后的状态如图,我们将1号和4号电梯人全部送到,1号到19楼送6人,4号到20楼送4人,地下室送1人,如图所示:

⑦ 电梯的大致功能如此,最后实现所有电梯一起运转,如图所示:

 

6、总结

      这次的编程用C语言图形库,界面不是现成的,而是需要自己画的,就画这个界面就花了大约一星期的时间,虽然麻烦,但是一个程序如果有一个好的界面用起来还是比较舒服的,所以再苦也值得了。代码不多,一共才500行不到,功能都实现了,主要用结构体来存储每个电梯和楼层的状态,再用图形学的画图函数,通过刷新率来统一绘制,相当于在统一的频率下更新状态并绘制图形。大致的思路是这样的,代码完完全全是我们自己编写,没有参考任何资料。

电梯调度基本算法:

      所用的调度算法与大家的大同小异,基本都是判断距离。如果有人按楼层上或下,则先判断4个电梯是否在此楼层停留筛选出一部分电梯,其次判断电梯上或下,是否与要乘坐电梯的人方向相同,筛选出一部分电梯,最后剩下的电梯如果大于1部,则判断电梯距离此楼层的距离,选出一部电梯进行调动。

 

7、easyx图形库下载及exe文件博客内地址下载:

要运行源码需要easyx图形库,点击安装到VC或VS目录即可:https://files.cnblogs.com/files/hgcrown/EasyX%E5%9B%BE%E5%BD%A2%E5%BA%93.zip

https://files.cnblogs.com/files/hgcrown/%E7%94%B5%E6%A2%AF%E8%B0%83%E5%BA%A6%E7%B3%BB%E7%BB%9F.zip

 

8、源代码

  1 # include <stdio.h>
  2 # include <graphics.h>
  3 # include <conio.h>
  4 # include <time.h>
  5 # include <memory.h>
  6 
  7 int x[4] = {570,570,570,570},k[4]={0,0,0,0},t[4]={0,0,0,0},di[4]={0,0,0,0};
  8 int cro,col;
  9 char s[10];
 10 int refresh_rate = 10;                                                                            //刷新率定义大小
 11 MOUSEMSG M;
 12 IMAGE ima,ima1,ima2,back,block;
 13 
 14 struct elevator                                                                                    //定义4个电梯结构体数组
 15 {
 16     int num,msum,dir,flo,mflo,numm,summ,elein[21],eleof[21],peom[21];
 17 }ele[5]={{0,0,2,1,1,10,800},{0,0,2,1,1,10,800},{0,0,2,1,1,20,1600},{0,0,2,1,1,20,2000}};
 18 
 19 struct floors                                                                                    //定义21个楼层结构体数组
 20 {
 21     int num[3],go,emin;
 22 }floor[21];
 23 
 24 void Draw1(int e)                                                                                //电梯接人路线绘制函数
 25 {
 26     if(t[e]==0)                                                                    //如果电梯没有到达目的楼层,则继续绘制路线
 27     {
 28         if (ele[e].dir==0)                                                //电梯上楼绘制
 29         {
 30             putimage(140+e*100,(20-ele[e].flo)*30-k[e],&ima);
 31             k[e]++;
 32             if (k[e]==30)
 33             {
 34                 ele[e].flo++;
 35                 k[e]=0;
 36             }
 37         }
 38         if (ele[e].dir==1)                                                //电梯下楼绘制
 39         {
 40             putimage(140+e*100,(20-ele[e].flo)*30+k[e],&ima);
 41             k[e]++;
 42             if (k[e]==30)
 43             {
 44                 ele[e].flo--;
 45                 k[e]=0;
 46             }
 47         }
 48         if (ele[e].dir==2)                                                //电梯停歇状态绘制
 49             putimage(140+e*100,(20-ele[e].flo)*30,&ima);
 50         if ((ele[e].flo==ele[e].mflo)&&(ele[e].dir!=2))                    //电梯到达目的楼层后的数值重新赋值
 51         {
 52             int h;
 53             ele[e].dir=2;
 54             floor[ele[e].flo].emin=22;
 55             t[e]=60;
 56             k[e]=0;
 57             while (floor[ele[e].mflo].num[0]!=0)                        //接人后电梯内部状态赋值
 58             {
 59                 h=rand()%41+50;
 60                 if ((ele[e].num+1<=ele[e].numm)&&(ele[e].msum+h<=ele[e].summ))
 61                 {
 62                     ele[e].num++;
 63                     ele[e].peom[ele[e].num-1]=h;
 64                     ele[e].msum=ele[e].msum+h;
 65                     floor[ele[e].flo].num[0]--;
 66                 }
 67                 else
 68                     break;
 69             }
 70             while (floor[ele[e].mflo].num[1]!=0)
 71             {
 72                 h=rand()%41+50;
 73                 if ((ele[e].num+1<=ele[e].numm)&&(ele[e].msum+h<=ele[e].summ))
 74                 {
 75                     ele[e].num++;
 76                     ele[e].peom[ele[e].num-1]=h;
 77                     ele[e].msum=ele[e].msum+h;
 78                     floor[ele[e].flo].num[1]--;
 79                 }
 80                 else
 81                     break;
 82             }
 83         }
 84     }
 85     if (t[e]!=0)                                                                //如果电梯到达目的楼层,则绘制电梯开门关门状态
 86     {
 87         if (t[e]>50)                                                    //开门
 88         {
 89             putimage(140+e*100-60+t[e]+5,(20-ele[e].flo)*30,&ima1);
 90             putimage(140+e*100+60-t[e]+5,(20-ele[e].flo)*30,&ima2);
 91             t[e]--;
 92         }
 93         else if (t[e]>10)
 94         {
 95             putimage(140+e*100-10+5,(20-ele[e].flo)*30,&ima1);
 96             putimage(140+e*100+11+5,(20-ele[e].flo)*30,&ima2);
 97             t[e]--;
 98         }
 99         else if (t[e]>0)                                                //关门
100         {
101             putimage(140+e*100-t[e]+5,(20-ele[e].flo)*30,&ima1);
102             putimage(140+e*100+t[e]+5,(20-ele[e].flo)*30,&ima2);
103             t[e]--;
104         }
105     }
106 }
107 
108 void Draw2(int e)                                                                                //电梯接人结束后,进入送客绘制模式
109 {
110     for (int v=0;v<=20;v++)                                                            //电梯内部按钮绘制
111     {
112         if ((v==0)&&(ele[e].elein[v]==1))
113             putimage(528+20%5*55,47+20/5*19.3+e*150,&block);
114         else if (ele[e].elein[v]==1)
115             putimage(528+(v-1)%5*55,47+(v-1)/5*19+e*150,&block);
116     }
117     if(t[e]==0)                                                                        //如果电梯没有到达目的楼层,则继续绘制路线
118     {    
119         if (ele[e].dir==0)                                                    //电梯上楼绘制
120         {
121             putimage(140+e*100,(20-ele[e].flo)*30-k[e],&ima);
122             k[e]++;
123             if (k[e]==30)
124             {
125                 ele[e].flo++;
126                 k[e]=0;
127             }
128         }
129         if (ele[e].dir==1)                                                    //电梯下楼绘制
130         {
131             putimage(140+e*100,(20-ele[e].flo)*30+k[e],&ima);
132             k[e]++;
133             if (k[e]==30)
134             {
135                 ele[e].flo--;
136                 k[e]=0;
137             }
138         }
139         if (ele[e].flo==ele[e].mflo)                                        //到达目的楼层后绘制
140         {
141             ele[e].elein[ele[e].flo]=0;
142             di[e]=0;
143             for (int v=0;v<=20;v++)
144                 if (ele[e].elein[v]==1)
145                     di[e]=1;
146             k[e]=0;
147             ele[e].dir=2;
148             while(ele[e].eleof[ele[e].flo]!=0)                                //电梯下人操作,重新赋值
149             {
150                 ele[e].num--;
151                 ele[e].msum=ele[e].msum-ele[e].peom[ele[e].num];
152                 ele[e].eleof[ele[e].flo]--;
153                 if (ele[e].num==0)
154                     break;
155             }
156             t[e]=60;
157         }
158     }
159     if (t[e]!=0)                                                                //如果电梯到达目的楼层,则绘制电梯开门关门状态                                                            
160     {
161         if (t[e]>50)                                                    //开门
162         {
163             putimage(140+e*100-60+t[e]+5,(20-ele[e].flo)*30,&ima1);
164             putimage(140+e*100+60-t[e]+5,(20-ele[e].flo)*30,&ima2);
165             t[e]--;
166         }
167         else if (t[e]>10)
168         {
169             putimage(140+e*100-10+5,(20-ele[e].flo)*30,&ima1);
170             putimage(140+e*100+10+5,(20-ele[e].flo)*30,&ima2);
171             t[e]--;
172         }
173         else if (t[e]>0)                                                //关门
174         {
175             putimage(140+e*100-t[e]+5,(20-ele[e].flo)*30,&ima1);
176             putimage(140+e*100+t[e]+5,(20-ele[e].flo)*30,&ima2);
177             t[e]--;
178         }
179     }
180 }
181 
182 void run ()                                                                                        //电梯运行总调度函数                                                                        
183 {    
184     int o,p,mine;
185     setcolor(BLACK);
186     while(1)                                                                            //电梯运行状态循环
187     { 
188         if(MouseHit())                                                            //如果触发鼠标时间
189         {
190             M = GetMouseMsg();                                                //鼠标事件获取
191             if (M.uMsg == WM_LBUTTONDOWN)                                    //如果鼠标左键单击
192             {
193                 if (M.x>=5&&M.x<=24)                                        //判断鼠标指针所在范围是否上楼
194                 {
195                     o=20-(M.y+1)/30;
196                     InputBox(s, 10, "请输入进电梯的人数");                    //弹窗响应,要求输入
197                     sscanf(s,"%d",&p);
198                     floor[o].num[0]=p;
199                 }
200                 if (M.x>=25&&M.x<=45)                                        //判断鼠标指针所在范围是否下楼
201                 {
202                     o=20-(M.y+1)/30;
203                     InputBox(s, 10, "请输入进电梯的人数");                    //弹窗响应,要求输入
204                     sscanf(s,"%d",&p);
205                     floor[o].num[1]=p;
206                 }
207                 if ((ele[0].num!=0)&&(M.x>=527&&M.x<=801&&M.y>=46&&M.y<=142))        //判断电梯内部按钮是否由鼠标响应
208                 {
209                     int r;
210                     cro=(M.x-528)/55;
211                     col=(M.y-46)/20;
212                     r=cro+col*5+1;
213                     if (r==21)
214                         r=0;
215                     di[0]=1;
216                     ele[0].mflo=r;
217                     ele[0].elein[ele[0].mflo]=1;
218                     InputBox(s, 10, "请输入此楼层要下电梯的人数");                    //弹窗响应,要求输入
219                     sscanf(s,"%d",&p);
220                     ele[0].eleof[ele[0].mflo]=p;
221                 }
222                 if ((ele[1].num!=0)&&(M.x>=527&&M.x<=801&&M.y>=196&&M.y<=292))        //判断电梯内部按钮是否由鼠标响应
223                 {
224                     int r;
225                     cro=(M.x-528)/55;
226                     col=(M.y-197)/20;
227                     r=cro+col*5+1;
228                     if (r==21)
229                         r=0;
230                     if (r%2==1)
231                     {
232                         di[1]=1;
233                         ele[1].mflo=r;
234                         ele[1].elein[ele[1].mflo]=1;
235                         InputBox(s, 10, "请输入此楼层要下电梯的人数");                //弹窗响应,要求输入
236                         sscanf(s,"%d",&p);
237                         ele[1].eleof[ele[1].mflo]=p;
238                     }
239                 }
240                 if ((ele[2].num!=0)&&(M.x>=527&&M.x<=801&&M.y>=346&&M.y<=442))        //判断电梯内部按钮是否由鼠标响应
241                 {
242                     int r;
243                     cro=(M.x-528)/55;
244                     col=(M.y-346)/20;
245                     r=cro+col*5+1;
246                     if (r==21)
247                         r=0;
248                     if (r%2==0)
249                     {
250                         di[2]=1;
251                         ele[2].mflo=r;
252                         ele[2].elein[ele[2].mflo]=1;
253                         InputBox(s, 10, "请输入此楼层要下电梯的人数");                //弹窗响应,要求输入
254                         sscanf(s,"%d",&p);
255                         ele[2].eleof[ele[2].mflo]=p;
256                     }
257                 }
258                 if ((ele[3].num!=0)&&(M.x>=527&&M.x<=801&&M.y>=496&&M.y<=592))        //判断电梯内部按钮是否由鼠标响应
259                 {
260                     int r;
261                     cro=(M.x-528)/55;
262                     col=(M.y-496)/20;
263                     r=cro+col*5+1;
264                     if (r==21)
265                         r=0;
266                     di[3]=1;
267                     ele[3].mflo=r;
268                     ele[3].elein[ele[3].mflo]=1;
269                     InputBox(s, 10, "请输入此楼层要下电梯的人数");                    //弹窗响应,要求输入
270                     sscanf(s,"%d",&p);
271                     ele[3].eleof[ele[3].mflo]=p;
272                 }
273             }
274         }
275         for(int j=20;j>=0;j--)                                                        //每个楼层开始判断是否有客人要上电梯的响应
276         {
277             mine=4;
278             if (floor[j].num[0]!=0)                                                //有上电梯响应且客人要上楼,开始电梯调度
279             {
280                 if ((ele[0].num<10)&&(ele[0].msum<800))                        //1号电梯条件是否满足
281                 {
282                     if ((j>=ele[0].flo)&&(ele[0].dir!=1))
283                         if (floor[j].emin>(j-ele[0].flo))
284                         {
285                             floor[j].emin=j-ele[0].flo;
286                             mine=0;
287                         }
288                     if ((j<ele[0].flo)&&(ele[0].dir==2))
289                         if (floor[j].emin>(ele[0].flo-j))
290                         {
291                             floor[j].emin=ele[0].flo-j;
292                             mine=0;
293                         }
294                 }
295                 if ((ele[3].num<20)&&(ele[3].msum<2000))                    //4号电梯条件是否满足
296                 {
297                     if ((j>=ele[3].flo)&&(ele[3].dir!=1))
298                         if (floor[j].emin>(j-ele[3].flo))
299                         {
300                             floor[j].emin=j-ele[3].flo;
301                             mine=3;
302                         }
303                     if ((j<ele[3].flo)&&(ele[3].dir==2))
304                         if (floor[j].emin>(ele[3].flo-j))
305                         {
306                             floor[j].emin=ele[3].flo-j;
307                             mine=3;
308                         }
309                 }
310                 if (j%2==0)
311                 {
312                     if ((ele[2].num<20)&&(ele[2].msum<1600))                //3号电梯条件是否满足
313                     {
314                         if ((j>=ele[2].flo)&&(ele[2].dir!=1))
315                             if (floor[j].emin>(j-ele[2].flo))
316                             {
317                                 floor[j].emin=j-ele[2].flo;
318                                 mine=2;
319                             }
320                         if ((j<ele[2].flo)&&(ele[2].dir==2))
321                             if (floor[j].emin>(ele[2].flo-j))
322                             {
323                                 floor[j].emin=ele[2].flo-j;
324                                 mine=2;
325                             }
326                     }
327                 }
328                 if (j%2==1)                                                    //2号电梯条件是否满足
329                 {
330                     if ((ele[1].num<10)&&(ele[1].msum<800))
331                     {
332                         if ((j>=ele[1].flo)&&(ele[1].dir!=1))
333                             if (floor[j].emin>(j-ele[1].flo))
334                             {
335                                 floor[j].emin=j-ele[1].flo;
336                                 mine=1;
337                             }
338                         if ((j<ele[1].flo)&&(ele[1].dir==2))
339                             if (floor[j].emin>(ele[1].flo-j))
340                             {
341                                 floor[j].emin=ele[1].flo-j;
342                                 mine=1;
343                             }
344                     }
345                 }
346                 if (j>=ele[mine].flo)                                        //用距离判断满足条件的电梯,在此筛选出满足条件电梯
347                     ele[mine].dir=0;
348                 else
349                     ele[mine].dir=1;                                        //满足条件的电梯设置目的楼层
350                 ele[mine].mflo=j;
351             }
352             if (floor[j].num[1]!=0)                                                //有上电梯响应且客人要下楼,开始电梯调度    
353             {
354                 if ((ele[0].num<10)&&(ele[0].msum<800))
355                 {
356                     if ((j<=ele[0].flo)&&(ele[0].dir!=1))
357                         if (floor[j].emin>(ele[0].flo-j))
358                         {
359                             floor[j].emin=ele[0].flo-j;
360                             mine=0;
361                         }
362                     if ((j>ele[0].flo)&&(ele[0].dir==2))
363                         if (floor[j].emin>(j-ele[0].flo))
364                         {
365                             floor[j].emin=j-ele[0].flo;
366                             mine=0;
367                         }
368                 }
369                 if ((ele[3].num<20)&&(ele[3].msum<2000))
370                 {
371                     if ((j<=ele[3].flo)&&(ele[3].dir!=1))
372                         if (floor[j].emin>(ele[3].flo-j))
373                         {
374                             floor[j].emin=ele[3].flo-j;
375                             mine=3;
376                         }
377                     if ((j>ele[3].flo)&&(ele[3].dir==2))
378                         if (floor[j].emin>(j-ele[3].flo))
379                         {
380                             floor[j].emin=j-ele[3].flo;
381                             mine=3;
382                         }
383                 }
384                 if (j%2==0)
385                 {
386                     if ((ele[2].num<20)&&(ele[2].msum<1600))
387                     {
388                         if ((j<=ele[2].flo)&&(ele[2].dir!=1))
389                             if (floor[j].emin>(ele[2].flo-j))
390                             {
391                                 floor[j].emin=ele[2].flo-j;
392                                 mine=2;
393                             }
394                         if ((j>ele[2].flo)&&(ele[2].dir==2))
395                             if (floor[j].emin>(j-ele[2].flo))
396                             {
397                                 floor[j].emin=j-ele[2].flo;
398                                 mine=2;
399                             }
400                     }
401                 }
402                 if (j%2==1)
403                 {
404                     if ((ele[1].num<10)&&(ele[1].msum<800))
405                     {
406                         if ((j<=ele[1].flo)&&(ele[1].dir!=1))
407                             if (floor[j].emin>(ele[1].flo-j))
408                             {
409                                 floor[j].emin=ele[1].flo-j;
410                                 mine=1;
411                             }
412                         if ((j>ele[1].flo)&&(ele[1].dir==2))
413                             if (floor[j].emin>(j-ele[1].flo))
414                             {
415                                 floor[j].emin=j-ele[1].flo;
416                                 mine=1;
417                             }
418                     }
419                 }
420                 if (j>=ele[mine].flo)
421                     ele[mine].dir=0;
422                 else
423                     ele[mine].dir=1;
424                 ele[mine].mflo=j;    
425             }
426         }
427         BeginBatchDraw();                                                    //开始画图
428         putimage(0,0,&back);
429         for (int i=0;i<4;i++)                                            //四个电梯一次绘制当前状态
430         {
431             if (di[i]==0)                                            //接客的电梯绘制
432                 Draw1(i);
433             if (di[i]==1)                                            //送客的电梯绘制
434             {
435                 if (ele[i].mflo>=ele[i].flo)                        //上楼绘制
436                 {
437                     ele[i].dir=0;
438                     for (int w=ele[i].flo;w<=20;w++)
439                     {
440                         if (ele[i].elein[w]==1)
441                         {
442                             ele[i].mflo=w;
443                             break;
444                         }
445                     }
446                 }
447                 else                                                //下楼绘制
448                 {
449                     ele[i].dir=1;
450                     for (int w=ele[i].flo;w>=0;w--)
451                     {
452                         if (ele[i].elein[w]==1)
453                         {
454                             ele[i].mflo=w;
455                             break;
456                         }
457                     }
458                 }
459                 Draw2(i);
460             }
461             setbkmode(TRANSPARENT);                                    //输出电梯当前状态数值
462             sprintf(s,"%d",ele[i].num);                                //电梯当前人数
463             outtextxy(890,49+i*150,s);
464             sprintf(s,"%d",ele[i].msum);                            //电梯当前重量
465             outtextxy(890,74+i*150,s);
466             sprintf(s,"%d",ele[i].flo);                                //电梯当前楼层
467             outtextxy(890,99+i*150,s);    
468         }
469         EndBatchDraw();                                        //结束绘制
470         Sleep(refresh_rate);                            //延时绘制,否则会本次绘制会遮挡下一次绘制
471     }
472     
473 }
474 
475 void main()                                                                    //主函数
476 {    
477     for (int i=0;i<21;i++)                                            //初始化
478     {
479         floor[i].num[0]=0;
480         floor[i].num[1]=0;
481         floor[i].emin=22;
482     }
483     initgraph(1000,630);                                            //构建窗口大小
484     loadimage(&back,"pic//2.jpg");                                    //载入图片2
485     putimage(0,0,&back);
486     loadimage(&ima,"pic//1.jpg");                                    //载入图片1            
487     loadimage(&ima1,"pic//3.jpg");                                    //载入图片3
488     loadimage(&ima2,"pic//4.jpg");                                    //载入图片4
489     loadimage(&block,"pic//5.jpg");                                    //载入图片5
490     BeginBatchDraw();                                                //初始化绘制
491     for (int j=0;j<4;j++)
492         putimage(140+j*100,(20-ele[j].flo)*30 ,&ima);
493     EndBatchDraw();                                                    //结束绘制
494     run();                                                            //进入电梯调度函数开始电梯总调度
495     closegraph();                                                //关闭窗口
496 }

 

posted @ 2016-04-07 18:36  hgcrown  阅读(1463)  评论(5编辑  收藏  举报