基于LOOK磁盘调度算法写一个电梯运行模拟器

来源:互联网 发布:js删除数组中元素 编辑:程序博客网 时间:2024/05/29 17:43

大四上学期的一门软件理论专题课要求课程结束之后写个大作业,在外苦逼实习一节课没上的我居然还要写这个玩意,怀着日乐购的心情随便选了一个电梯模拟系统的题。
题目拿到手,首先考虑要不就写了大一时期的字符界面的吧,转念一想字符界面还是不符合我的气质,所以我又搬出牛逼哄哄的DuiLib界面库,虽然这个界面库已经停止维护了,不过怎么说人家现在也还是微信采用的界面库啊,这里附上写的很好的一篇duilib教程
,然后仔细研究了一下电梯的运行原理,为此下班上楼时专门仔细注意了一下电梯,后来百度一下发现原来这个叫做LOOK磁盘调度算法,这里你可能会疑惑为什么电梯的运行算法扯到了磁盘调度,因为电梯运行时类似于磁盘寻道,磁盘寻道时通常是磁头运行到相应的请求的磁道再将数据读入内存,LOOK调度算法的原理是每次只运行到最外层的请求道就返回,举个例子:


假设某个磁盘磁道编号为1~200,当前磁头的位置在100, 请求序列为 : 45 、 99 、 160 、 3
这时磁头的访问顺序就是160、99、45、3


在电梯的实际运行中包含上楼的请求、下楼的请求和进入电梯之后需要前往的目标层,采用LOOK算法之后,若电梯当前处在向上运行的状态电梯会一直运行到最高的请求层之后,再调转方向,反正同理。
我采用了链表来存储请求层和目标层,上向请求层升序排列,下向请求层降序排列这样可方便拿到最高的请求层和最低的请求层,建立一个电梯对象来标识电梯的位置,在循环中监控电梯的位置是否到达目标点,话不多说直接上代码:

while(1)    {           bool isArrive =false;    if(elevator->getStatus())                  //电梯是否在运行,若在运行再看运行方向    {        ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);        if(elevator->isUp())        {            elevator->Upstairs();                               ::PostMessage(hWnd, WM_REDRAW, 0L, 0);            if(request_down_head != NULL)            {                if(request_down_head->floor == elevator->getFloor())                {                    ::PostMessage(hWnd, WM_CHANGEDBTNCOLOR, 0L, 0);                    //到达了最高的一个下向请求层                    FreeDownRequest(request_down_head);                    ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                    isArrive = true;                    elevator->setDown();                }            }            else if(FindRequestUp(elevator->getFloor()))            {                ::PostMessage(hWnd, WM_CHANGEUBTNCOLOR, 0L, 0); //到达了上向请求层                ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                isArrive = true;            }            if(FindTarget(elevator->getFloor()))            {                ::PostMessage(hWnd, WM_CHANGENBTNCOLOR, 0L, 0);                 ::MessageBox(NULL, _T("到达了目标楼层,开门!"), _T("注意安全"), NULL);                isArrive = true;            }        }        else if(elevator->isDown())        {            elevator->Downstairs();            ::PostMessage(hWnd, WM_REDRAW, 0L, 0);                              if(request_up_head != NULL)            {                if(request_up_head->floor == elevator->getFloor())                {                    ::PostMessage(hWnd, WM_CHANGEUBTNCOLOR, 0L, 0);                    ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                    FreeUpRequest(request_up_head);                    isArrive = true;                    elevator->setUp();                }            }            else if(FindRequestDown(elevator->getFloor()))            {                ::PostMessage(hWnd, WM_CHANGEDBTNCOLOR, 0L, 0);                ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                isArrive = true;            }            if(FindTarget(elevator->getFloor()))            {                //::PostMessage(hWnd, WM_CHANGEUBTNCOLOR, 0L, 0); //到达了上向请求层                ::PostMessage(hWnd, WM_CHANGENBTNCOLOR, 0L, 0);                ::MessageBox(NULL, _T("到达了目标楼层,开门!"), _T("注意安全"), NULL);                isArrive = true;            }        }        if(target_head == NULL && request_down_head == NULL && request_up_head == NULL) //没有目标了就停下来        {            //::MessageBox(NULL, _T("停!"), _T("注意安全"), NULL);            elevator->stop();        }        if(isArrive)        {            ::Sleep(5000);            ::MessageBox(NULL, _T("电梯关门!"), _T("注意安全"), NULL);            if(target_head == NULL)            {                if(elevator->isDown() && request_down_head == NULL && request_up_head != NULL)                {                    if(request_up_head->floor >= elevator->getFloor())                    {                        elevator->setUp();                    }                }                if(elevator->isUp() &&  request_up_head != NULL && request_down_head == NULL)                {                    if(request_up_head->floor <= elevator->getFloor())                    {                        elevator->setDown();                    }                }            }        }        if(!elevator->getStatus())        {            ::PostMessage(hWnd, WM_TARBTNCLOSE, 0L, 0);        }    }    else                    //当前状态为停止时:    {        /**/        if(request_down_head != NULL)  //有下向请求层时,设置状态为运行,根据位置设置方向        {            if(request_down_head->floor > elevator->getFloor())            {                elevator->setUp();                elevator->run();            }else if(request_down_head->floor == elevator->getFloor())            {                ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                FreeDownRequest(request_down_head);                ::PostMessage(hWnd, WM_CHANGEDBTNCOLOR, 0L, 0);                ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);                elevator->setDown();                ::Sleep(5000);                ::MessageBox(NULL, _T("电梯关门!"), _T("注意安全"), NULL);            }            else            {                elevator->setDown();                elevator->run();            }                           ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);        }        else if(request_up_head != NULL) //有上向请求层时,设置状态为运行,根据位置设置方向        {            if(request_up_head->floor > elevator->getFloor())            {                elevator->setUp();                elevator->run();            }            else if(request_up_head->floor == elevator->getFloor())            {                ::MessageBox(NULL, _T("到达请求楼层,开门!"), _T("注意安全"), NULL);                FreeUpRequest(request_up_head);                ::PostMessage(hWnd, WM_CHANGEUBTNCOLOR, 0L, 0);                ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);                elevator->setUp();                ::Sleep(5000);                ::MessageBox(NULL, _T("电梯关门!"), _T("注意安全"), NULL);            }            else             {                elevator->setDown();                elevator->run();            }            ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);        }        else if(target_head != NULL)   //有目标层时,设置状态为运行,根据位置设置方向            {                if(target_head->floor > elevator->getFloor())                {                    elevator->setUp();                    elevator->run();                }else if(target_head->floor == elevator->getFloor())                {                    ::MessageBox(NULL, _T("到达目标层,开门!"), _T("注意安全"), NULL);                    FreeTarget(target_head);                    ::PostMessage(hWnd, WM_CHANGENBTNCOLOR, 0L, 0);                    ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);                    //elevator->setUp();                    ::Sleep(20000);                }                else                {                    elevator->setDown();                    elevator->run();                }                ::PostMessage(hWnd, WM_TARBTNOPEN, 0L, 0);            }    }       ::Sleep(500);    }

这里更新软件界面是采用MFC的消息映射来完成,界面的进程和逻辑的进程需要同步运行
最终写出来的软件长这样:
这里写图片描述
迷之界面有没有…哈哈哈

具体项目已上传至GitHub
上传至GitHub