📄 elevator.c
字号:
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 + -