⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elevator.c

📁 The goal of our final project was to design an efficient elevator simulator that can accept input fr
💻 C
📖 第 1 页 / 共 2 页
字号:
void addRequests()
{
    //Just send 1 elevator to do everything!
    if(mode==trivial)
    {
        algorithm1(elevator1);
    }
    else if(mode==simple)
    {
        algorithm1(elevator1);
        algorithm1(elevator2);
        algorithm1(elevator3);
    }
    else if(mode == normal)
    {
        algorithm2();
    }
    else if(mode == sabbath)
    {
        if(elevator3->floor == (floors+floors-2)/3  && !elevator3->paused)
            ready2 = 1;
        if(elevator2->floor == (floors+floors-2)/3  && !elevator2->paused)
            ready1 = 1;
        if(ready1)
            algorithm3(elevator1);
        if(ready2)
            algorithm3(elevator2);
        algorithm3(elevator3);
    }
}

void oneStep(elevator_t elevator) //main state machine
{
    int x,i, flag = 0;
    if(elevator->paused)
    {
        if((elevator->uprequests[elevator->floor] && elevator->traveldir == 1) ||
           (elevator->downrequests[elevator->floor] && elevator->traveldir == -1) || elevator->button[elevator->floor])
        {
            i = elevator->floor;
            //printf("Elevator #%i Doors remaining open (button held down)\r\n",elevator->id);
            elevator->paused = pause;
            //request satisfied
            if(elevator->traveldir == 1) //this could be wrong
            {
                        elevator->uprequests[i] = 0;
                  }
                  else
                  {
                        elevator->downrequests[i] = 0;
                  }
            button2[((i<<2) + 1 + elevator->traveldir)>>1] = 0;
            button[((i<<2) + 1 + elevator->traveldir)>>1] = 0;
            elevator->button[elevator->floor] = 0;
        }

        elevator->paused--;
        if(elevator->paused==0)
        {
            //printf("Elevator #%i Doors closing\r\n",elevator->id);
            printf("closing%i\r\n",elevator->id);
        }
    }
    else
    {
        //just hit a floor or idling on floor
        if(elevator->count==floorsize || elevator->count == 0)
        {
            if(elevator->count == 0) //idling on a floor
            {
                if(elevator->button[elevator->floor])
                {
                    flag = 1;
                    elevator->button[elevator->floor] = 0;
                }
            }
            //just hit a floor, update floor number and display it
            if(elevator->count==floorsize)
            {
                elevator->floor = elevator->floor + elevator->traveldir;
                //if we are going to stop at this floor, update button
                //before calling checkdirection
                if(elevator->button[elevator->floor])
                {
                    flag = 1;
                    elevator->button[elevator->floor] = 0;
                }
                checkdirection(elevator);
                if(elevator->floor==elevator->turnaround)
                    elevator->traveldir = 0 - elevator->traveldir;

                printf("arrived%i%02i\r\n",elevator->id,elevator->floor);
                elevator->count = 0;
            }
            //passenger wants to get off on this floor, so elevator needs to stop
            if(flag)
            {
                printf("opening%i%i\r\n",elevator->id,elevator->traveldir+1);
                elevator->paused = pause;
                //requests to get on in same direction satisfied
                if(elevator->floor == elevator->turnaround) //elevator is turning around here, can satisfy other elevator requests
                {
                  if(elevator->traveldir == 1)
                  {
                      elevator1->downrequests[elevator->floor] = 0;
                      elevator2->downrequests[elevator->floor] = 0;
                      elevator3->downrequests[elevator->floor] = 0;
                  }
                  else
                  {
                      elevator1->uprequests[elevator->floor] = 0;
                      elevator2->uprequests[elevator->floor] = 0;
                      elevator3->uprequests[elevator->floor] = 0;
                  }
                  x = ((elevator->floor<<2) + 1 - elevator->traveldir)>>1;
                }
                else //elevator is continuing on, can satisfy other elevator requests
                {
                    if(elevator->traveldir == 1)
                    {
                        elevator1->uprequests[elevator->floor] = 0;
                        elevator2->uprequests[elevator->floor] = 0;
                        elevator3->uprequests[elevator->floor] = 0;
                    }
                    else
                    {
                        elevator1->downrequests[elevator->floor] = 0;
                        elevator2->downrequests[elevator->floor] = 0;
                        elevator3->downrequests[elevator->floor] = 0;
                    }

                    //turn off outside button
                    x = ((elevator->floor<<2) + 1 + elevator->traveldir)>>1;
                }
                button2[x] = 0;
            }
            //there is an outside request in the direction of travel, open to pick them up
            if((elevator->traveldir == 1 && elevator->uprequests[elevator->floor]) || (elevator->traveldir == -1 && elevator->downrequests[elevator->floor]) )
            {
                //printf("Elevator #%i doors opening to pick someone up\r\n",elevator->id);
                printf("opening%i%i\r\n",elevator->id,elevator->traveldir+1);
                elevator->paused = pause;
                //request to pick up on this floor satisfied
                if(elevator->traveldir == 1)
                {
                    elevator->uprequests[elevator->floor] = 0;
                }
                else
                {
                    elevator->downrequests[elevator->floor] = 0;
                }

                //turn  off outside button
                x = ((elevator->floor<<2) + 1 + elevator->traveldir)>>1;
                button2[x] = 0;
                button[x] = 0;
            }
            if(!elevator->paused)
            {
                x = checkdirection(elevator); //we need to check again after new passengers have gotten on.
                if(elevator->floor == elevator->turnaround) //this is where we turn around
                {
                    elevator->traveldir = 0 - elevator->traveldir; //switch directions
                    //printf("Switched directions to %i\r\n",elevator->traveldir);
                }
                if(x)
                    elevator->on = 1;
            }
        }
        //don't turn around mid-floor
        else
        {
            elevator->on = 1;
        }
    }
}

int hasrequests(elevator_t elevator, int requestfloor, int requestdirection)//checks if an elevator has requests and returns 200*numrequests
{
    int i, sum = 0;
    if(elevator->paused && elevator->floor != requestfloor) //add distance if elevator is stopped on another floor
        sum = sum + 200;
    for(i=0; i<floors; i++)
    {
        if(elevator->downrequests[i]||elevator->uprequests[i]||elevator->button[i])
        {
            //add distance if elevator has a request on another floor or in the opposite direction
            if(i != requestfloor || (elevator->uprequests[i] && requestdirection == -1) || (elevator->downrequests[i] && requestdirection == 1))
                sum = sum + 200;
        }
    }
    return sum;

}


int distance(elevator_t elevator, int requestfloor, int requestdirection)
{
    int elevatorfloor, requests;
    requests = hasrequests(elevator,requestfloor,requestdirection);
    elevatorfloor = elevator->floor;
    if(!requests)
        return abs(elevator->floor - requestfloor);
    //if elevator is moving then its floor must be updated to the next floor it will pass
    if(!elevator->paused)
      elevatorfloor = elevatorfloor + elevator->traveldir;
    //worst and best cases, elevator heading in same direction as request
    if(elevator->traveldir==requestdirection)
    {
        //best case, elevator on way to request
        if((elevator->traveldir==1 && elevatorfloor<=requestfloor)||(elevator->traveldir==-1 && elevatorfloor>=requestfloor))
        {
            return requests + abs(requestfloor - elevatorfloor);
        }
        //worst case, elevator needs to switch direction twice
        else
        {
            return requests + floors+floors - abs(requestfloor - elevatorfloor);
        }
    }
    //elevator needs to switch direction once
    else
    {
        //elevator heading to top floor
        if(elevator->traveldir==1)
        {
            return requests + (floors-1-elevatorfloor)+(floors-1-requestfloor);
        }
        //elevator heading to bottom floor
        else
        {
            return requests + elevatorfloor+requestfloor;
        }
    }

}

void algorithm1(elevator_t elevator) //for trivial and simple modes
{
    int i;
    for(i=1;i<floors+floors-1;i++) //add all outside requests to elevator 1 for now
    {
        if(button[i]) //button is pressed
        {
          if(i%2 == 1) //this is an up button
          {
            elevator->uprequests[i>>1] = 1;
          }
          else //this is a down button
          {
           elevator->downrequests[i>>1] = 1;
          }
          if(mode!=trivial && elevator->id==3)
            button[i] = 0; //button turns off, request received

        }
    }
}

void algorithm2() //for normal mode
{
    int i;
    int d1;
    int d2;
    int d3;
    elevator_t choice;
    for(i=1;i<floors+floors-1;i++) //loop through outside buttons
    {
        if(button[i]) //button is pressed
        {
            //if elevator is already open on this floor, give request to that elevator
            if(elevator1->paused && elevator1->floor == (i>>1) && elevator1->traveldir==i%2)
            {
              if(i%2 == 1) //up button
                elevator1->uprequests[elevator1->floor] = 1;
              else //down button
                elevator1->downrequests[elevator1->floor] = 1;
            }
            else if(elevator2->paused && elevator2->floor == (i>>1) && elevator2->traveldir==i%2)
            {
              if(i%2 == 1) //up button
                elevator2->uprequests[elevator2->floor] = 1;
              else //down button
                elevator2->downrequests[elevator2->floor] = 1;
            }
            else if(elevator3->paused && elevator3->floor == (i>>1) && elevator3->traveldir==i%2)
            {
              if(i%2 == 1) //up button
                elevator3->uprequests[elevator3->floor] = 1;
              else //down button
                elevator3->downrequests[elevator3->floor] = 1;
            }
            //otherwise, calculate distances and compare
            else
            {
                if(i%2 == 1) //this is an up button
                {
                    d1 = distance(elevator1,i>>1,1);
                    d2 = distance(elevator2,i>>1,1);
                    d3 = distance(elevator3,i>>1,1);
                }
                else //this is a down button
                {
                    d1 = distance(elevator1,i>>1,-1);
                    d2 = distance(elevator2,i>>1,-1);
                    d3 = distance(elevator3,i>>1,-1);
                }
                if(d1<=d2 && d1<=d3)
                    choice = elevator1;
                else if(d2<=d3)
                    choice = elevator2;
                else
                    choice = elevator3;

                if(i%2 == 1) //this is an up button
                {
                    choice->uprequests[i>>1] = 1;
                }
                else //this is a down button
                {
                    choice->downrequests[i>>1] = 1;
                }
            }
            button[i] = 0;
        }
    }
}

void algorithm3(elevator_t elevator) //for sabbath mode
{
    int i;
    for(i = 0; i< floors; i++)
    {
        if((elevator->floor != i))
        {
            if(i>0)
                elevator->downrequests[i] = 1;
            if(i<floors-1)
                elevator->uprequests[i] = 1;
        }

    }
}

void poll2()
{
    int x;
    elevator_t elevator = NULL;
    if(!serialFlag)
        return;
    serialFlag = 0;
    buffer[bufferindex] = getchar();
    if(buffer[bufferindex]=='z')
    {
        if(bufferindex>=3 && buffer[bufferindex-3]=='o')
        {
            x = ((int)buffer[bufferindex-2]-48)*10+(int)buffer[bufferindex-1]-48;
            if (x>0 && x<2*floors-1 && !button2[x])
            {
                button[x] = 1;
                button2[x] = 1;
            }
        }
        else if(bufferindex>=4 && buffer[bufferindex-4]=='i')
        {
            x = ((int)buffer[bufferindex-2]-48)*10+(int)buffer[bufferindex-1]-48;
            if(buffer[bufferindex-3]=='1')
                elevator = elevator1;
            else if(buffer[bufferindex-3]=='2')
                elevator = elevator2;
            else if(buffer[bufferindex-3]=='3')
                elevator = elevator3;

            if(elevator != NULL && x>=0 && x< floors)
            {
                elevator->button[x] = 1;
            }
        }
        bufferindex=0;
    }
    else
        bufferindex++;

    if(bufferindex>=8)
        bufferindex = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -