package ele;
import java.util.LinkedList;
import java.util.Queue;
class Elevator
{
private int id;
private int currentFloor;//当前楼层
private int[] ableFloor;//电梯所能到得楼层
private int flag;//0,停;1,向上;2,向下
private int status;//0,等待;1,运行;2,停(乘客在进出电梯)
private int runTime=0;//运行时间
private int idleTime=0;//闲置时间
private Queue<Passenger>waitQueue;//等待队列
private LinkedList<Passenger>carryList;//乘梯列表
private int passengerSum=0;//电梯中乘梯人数
private int up=0;//控制电梯,s秒上一层
private int down=0;//控制电梯,s秒下一层
private int intoElevator=0;//控制人上电梯时间
private int outElevator=0;//控制人上电梯时间
//private int oldTime=0;
Elevator(int id,int currentFloor,int []ableFloor,int flag)
{
this.id=id;
this.currentFloor=currentFloor;
this.ableFloor=ableFloor;
this.flag=flag;
waitQueue=new LinkedList<Passenger>();//空的等待队列
carryList=new LinkedList<Passenger>();//空的乘梯队列
}
public int getId()
{
return id;
}
public int getFlag()
{
return flag;
}
public void setFlag(int flag)
{
this.flag=flag;
}
public void setStatus(int status)
{
this.status=status;
}
public int getStatus()
{
return status;
}
public int getCurrentFloor()
{
return currentFloor;
}
public int[] getAbleFloor()
{
return ableFloor;
}
public Queue<Passenger> getWaitQueue()
{
return waitQueue;
}
public Queue<Passenger> getCarryQueue()
{
return carryList;
}
public int getRunTime()
{
return runTime;
}
public int getIdleTime()
{
return idleTime;
}
public boolean isAbleFloor(int floor)//判断电梯能否到floor层
{
for(int f:this.getAbleFloor())
{
if(f==floor)
return true;
}
return false;
}
public int getMinFloor()//电梯向下运行时,得到电梯乘客列表中的要去的最低楼层
{
if(this.carryList.size()==0)//电梯承载队列为空
return 1;
int MinFloor=40;
for(Passenger p:this.getCarryQueue())
{
if(p.getCurrentFloor()<MinFloor)
MinFloor=p.getCurrentFloor();
}
return MinFloor;
}
public int getMaxFloor()//电梯向上运行时,得到电梯乘客列表中的要去的最高楼层
{
if(this.carryList.size()==0)
return 40;
int MaxFloor=1;
for(Passenger p:this.getCarryQueue())
{
if(p.getCurrentFloor()>MaxFloor)
MaxFloor=p.getCurrentFloor();
}
return MaxFloor;
}
public void upRun()//电梯向上运行一秒
{
if(this.currentFloor==40)
{
this.flag=2;//向下
return;
}
this.runTime++;//运行时间加1
this.up++;
if(this.up==Param.S)
{
this.currentFloor++;
this.up=0;
}
}
public void downRun()//电梯向下运行一秒
{
if(this.currentFloor==1)
{
this.flag=1;//向上
return;
}
this.runTime++;//运行时间加1
this.down++;
if(this.down==Param.S)
{
this.currentFloor--;
this.down=0;
}
}
public void continueRun()//电梯继续运行1秒
{
if(this.flag==1&&this.status==1)//向上运行
this.upRun();
else if(this.flag==2&&this.status==1)
this.downRun();//向下运行
else
{
this.idleTime++;//闲置时间加1
}
}
public boolean checkStop(Floor currentFloor)//电梯运行到currentFloor时,判断是否需要停
{
if(currentFloor.getId()>40||currentFloor.getId()<1)
return false;
if(this.isAbleFloor(currentFloor.getId())==false)
return false;
//判断当前层是否有人下
if(this.carryList.size()>0)
{
for(Passenger p:this.carryList)
{
//if(p.getStatus()==3)
//continue;
if(p.getDestFloor()==currentFloor.getId())
return true;
}
}
//当前层没人下,判断电梯是否已满
if(this.passengerSum==Param.K)//电梯已满
return false;
//不满,判断是否有人上
/*
if(currentFloor.getId()==1||currentFloor.getId()==40)
return true;
*/
if(this.waitQueue.size()>0)
for(Passenger p:this.waitQueue)
if(p.getCurrentFloor()==currentFloor.getId())//如果p所在楼层等于电梯当前所在楼层,则要上电梯
return true;
return false;
}
public void takeElevator(Floor currentFloor,int currentTime)//在时间为currentTime,楼层为currentFloor时,处理乘客上下电梯事件
{
if(currentFloor.getId()>40||currentFloor.getId()<1)
return;
if(this.checkStop(currentFloor)==true)//当前层有请求,处理上下电梯活动
{
int f=this.flag;//保存电梯方向
this.status=2;//设置状态为2
//先下后上
//当前层有人下
//this.currentFloor=currentFloor.getId();
if(this.carryList.size()>0)
{
LinkedList<Passenger> delList = new LinkedList<Passenger>();//辅助队列
for(Passenger p:this.carryList)
{
if(p.getDestFloor()!=currentFloor.getId())
continue;
if(p.getDestFloor()==currentFloor.getId())//p要下电梯
{
if(this.intoElevator<Param.T)//控制p下电梯时间为T
{
this.intoElevator++;
return;
}
if(p.getRideSum()==p.getL()+1)//p完成乘梯活动
{
p.setStatus(3);
//Passenger.overSum++;//完成数加1
this.passengerSum--;//乘梯人数减1
//System.out.println("乘客"+p.getId()+"到第"+currentFloor.getId()+"层,从电梯"+this.id+"出来,完成所有乘梯活动,目前共有"+Passenger.overSum+"人完成");
delList.offer(p);//将p从乘客队列删除,先加入辅助队列
}
else if(p.getRideSum()==p.getL())
{
//System.out.println("乘客"+p.getId()+"到第"+currentFloor.getId()+"层,从电梯"+this.id+"出来");
p.setCurrentFloor(currentFloor.getId());//设置乘客当前楼层
p.setDestFloor(1);//设下一次目标楼层为1
this.passengerSum--;//乘梯人数减1
//System.out.println("乘客"+p.getId()+"到第"+currentFloor.getId()+"层,从电梯"+this.id+"出来。下一次要去"+p.getDestFloor()+"层");
p.setNextRequestTime(currentTime+p.getStayTime());//设置下一次请求时间
currentFloor.getIdleQueue().offer(p);//p插入楼层的闲置队列
p.setResponse(false);//乘客从电梯出来设置响应标志位false
delList.offer(p);//将p从乘客队列删除,先加入辅助队列
}
else
{
p.setCurrentFloor(currentFloor.getId());//设置乘客当前楼层
p.setDestFloor(p.getNextDestFloor());//随机产生下一次目标楼层
this.passengerSum--;//乘梯人数减1
//System.out.println("乘客"+p.getId()+"到第"+currentFloor.getId()+"层,从电梯"+this.id+"出来。下一次要去"+p.getDestFloor()+"层");
p.setNextRequestTime(currentTime+p.getStayTime());//设置下一次请求时间
currentFloor.getIdleQueue().offer(p);//p插入楼层的闲置队列
p.setResponse(false);//乘客从电梯出来设置响应标志位false
delList.offer(p);//将p从乘客队列删除,先加入辅助队列
}
//this.intoElevator=0;//标志清0
}
}
this.carryList.removeAll(delList);
//System.out.println("电梯内乘客数"+this.carryQueue.size());
}
if(this.carryList.size()==0)//电梯人全部下完
{
this.flag=0;
this.status=0;
}
//当前层有人要上
if(this.waitQueue.size()>0)
{
Queue<Passenger> delList = new LinkedList<Passenger>();
for(Passenger p:this.waitQueue)
{
if(this.passengerSum==Param.K)//电梯已满
break;
if(p.getCurrentFloor()!=this.currentFloor)//p不能在当前层上
continue;
if(p.getRequestFlag()==this.flag||this.flag==0)//当电梯方向与乘客请求方向一致,或电梯方向为0时,p进入电梯
{
if(this.outElevator<Param.T)//控制p上电梯时间为T
{
this.outElevator++;
return;
}
p.setRideSum(p.getRideSum()+1);//p乘梯次数加1
this.passengerSum++;//乘梯人数加1
p.setWaitTime(p.getWaitTime()+currentTime-p.getNextRequestTime());//乘客等待时间增加currentTime-p.getNextRequestTime()
//System.out.println("乘客"+p.getId()+"第"+p.getRideSum()+"次在"+currentFloor.getId()+"层进入电梯"+this.id+"要去第"+p.getDestFloor()+"层");
currentFloor.getWaitQueue().remove(p);//p从楼层等待队列删除
this.carryList.offer(p);//p加入乘梯队列
delList.offer(p);//将p插入队列delList
}