📄 define.pas
字号:
procedure TElavotor.TakeElavotor(CurrentFloor:integer);
var i,j,k,iDown,MaxDest:integer;
Tempstr,str,AddStr:string;
Del:TstringList;
LockThread:TThreadlist;
begin
LockThread:=TThreadlist.Create;
LockThread.Add(Floor[CurrentFloor].Requestlist); //加入锁定共享数据列表
LockThread.Add(Floor[CurrentFloor].Idlelist);
LockThread.Add(self.OuterRequestArray);
LockThread.LockList; //锁定共享数据对象
self.Speed:=ElavotorSpeed;
self.MaxLoadCapacity:=self.InsideRequestArray.Count;
Del:=Tstringlist.Create;
if (CurrentFloor>40) or (CurrentFloor<1) then exit;
if self.CheckStop(CurrentFloor) then
begin
//当前层有人下
iDown:=self.InsideRequestArray.Count-1;
for i:=0 to iDown Do
begin
Tempstr:=self.InsideRequestArray.Strings[i];
Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
j:=Strtoint(Str);
if person[j].DestinationFloor=CurrentFloor then
begin
if person[j].FinishedCount=TakeNum+1 then
begin
person[j].MissionCompleted:=true;
Continue;
end;
person[j].CurrentFloor:=CurrentFloor;
person[j].SelectedElavotorID:=0;
person[j].FinishedCount:=person[j].FinishedCount+1;
person[j].PersonStatus:=PersonStatus_idle;
Del.Add(Tempstr);
K:=Elavotor_Memo[self.ID].Lines.IndexOf(Tempstr);
if k>=0 then
Elavotor_Memo[self.ID].Lines.Delete(k);
k:=Random(100)+20;
Addstr:=inttostr(j)+'-'+inttostr(systemControl.SimTimeTotal)+':'+inttostr(k);
Floor[CurrentFloor].Idlelist.Add(Addstr); //加入闲置队列UserID-basetime:idletime
end;
end;
//删除当前楼层等待队列中以上电梯的人员
for i:=0 to Del.Count-1 Do
if Del.Strings[i]<>'' then
begin
k:=self.InsideRequestArray.IndexOf(Del.Strings[i]);
if k>=0 then
self.InsideRequestArray.Delete(k);
end;
//当前层有人上
iDown:= Floor[CurrentFloor].Requestlist.Count-1; //计算当前楼层等待人数
Del.Clear;
for i:=0 to iDown Do //判断等待队列中每个人是否要上当前电梯
begin
Tempstr:=Floor[CurrentFloor].Requestlist.Strings[i];
Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
j:=Strtoint(Str);
if person[j].CurrentFloor<>self.CurrentFloor then Continue else //是否电梯到达乘客当前楼层
if person[j].SelectedElavotorID = Self.ID then
begin
if self.CurrentFloor=1 then self.Direction:=1;
if self.CurrentFloor=40 then self.Direction:=2;
if self.CurrentLoadCapacity=MaxLoad then //电梯是否已经满员
begin
self.isFull:=true;
Break;
end;
self.CurrentLoadCapacity:=self.CurrentLoadCapacity+1; //增加当前乘客
Addstr:=inttostr(j)+'-'+inttostr(Person[j].DestinationFloor);
self.InsideRequestArray.Add(Addstr); //把当前乘客加入内部乘梯队列
Elavotor_Memo[self.ID].Lines.Add(Addstr);
k:=self.OuterRequestArray.IndexOf(Addstr);
if k>=0 then
Elavotor[self.ID].OuterRequestArray.Delete(k); //删除当前乘客在电梯外的等待队列信息
person[j].PersonStatus:=PersonStatus_Taking; //置上当前电梯的人的状态为乘做
Del.Add(Tempstr);
end;
end;
//删除当前楼层等待队列中以上电梯的人员
for i:=0 to Del.Count-1 Do
if Del.Strings[i]<>'' then
begin
K:=Floor[CurrentFloor].Requestlist.IndexOf(Del.Strings[i]);
if k>=0 then
Floor[CurrentFloor].Requestlist.Delete(K);
end;
Del.Free;
//改变电梯目标楼层
MaxDest:=Self.DestFloorLayer;
iDown:= self.InsideRequestArray.Count-1;
if (self.CurrentFloor<>1) or (self.CurrentFloor<>40) then
for i:=0 to iDown Do
begin
Tempstr:=self.InsideRequestArray.Strings[i];
Str:=Copy(Tempstr,0,pos('-',Tempstr)-1); //UserID-DestFloor
j:=Strtoint(Str); //取得乘客编号
k:=strtoint(copy(Tempstr,pos('-',Tempstr)+1,length(Tempstr)-pos('-',Tempstr)+1));
if self.Direction=Person[j].Direction then
if MaxDest<k then MaxDest:=k; //电梯到达的最大楼层
end;
Self.DestFloorLayer:=MaxDest;
end;
LockThread.UnlockList;
LockThread.Free;
end;
procedure TElavotor.UPrun;
begin
if (self.CurrentFloor=40) then
begin
self.Direction:=2;
exit;
end;
self.CurrentFloor:=self.CurrentFloor+ElavotorSpeed;
if Self.CurrentFloor>40 then Self.CurrentFloor:=40;
self.nBusyTime:=self.nBusyTime+1;
ElavotorTrack[self.ID].Position:=1-self.CurrentFloor;
Elavotor_Busy_Label[self.ID].Caption :=inttostr(self.nBusyTime);
if not CanTake(self.ID,self.CurrentFloor) then exit; //如果当前楼层不能停,就继续上
self.TakeElavotor(Self.CurrentFloor);
end;
{ TPerson }
function CanTake(ElavotorID,Destlayer: integer):Boolean;
begin
Result:=false;
case ElavotorID of
0,1:begin Result:=true; exit; end;
2,3:begin if (Destlayer=1) or (Destlayer>=25) and (Destlayer<=40) then Result:=true else Result:=false; exit;end;
4,5:begin if Destlayer<=25 then Result:=true; exit;end;
6,7:begin if (Destlayer=1) or (Destlayer>=2) and (Destlayer<=40) then
if (Destlayer mod 2)=0 then Result:=true else Result:=false; exit;end;
8,9:begin if (Destlayer=1) or (Destlayer<=25) and (Destlayer<=39) then
if not ((Destlayer mod 2)=0) then Result:=true else Result:=false; exit; end;
end;
end;
function TPerson.ChooseElavotor(CurrentFloor,DestinationFloor: integer): integer;
var i,j,iTemp:integer;
CanTakeElavotor:array[0..9] of integer;
begin
Result:=0;
iTemp:=41;
if self.CurrentFloor=1 then
begin
for i:=0 to 9 DO
if CanTake(i,self.DestinationFloor) then
begin
if Elavotor[i].Direction=2 then
if Elavotor[i].OuterRequestArray.Count<Maxload then
CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor)
else CanTakeElavotor[i]:=41
else CanTakeElavotor[i]:=41;
end else CanTakeElavotor[i]:=41;
end else if self.CurrentFloor=40 then
begin
for i:=0 to 9 DO
if CanTake(i,self.DestinationFloor) then
begin
if Elavotor[i].Direction=1 then
CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor)
else CanTakeElavotor[i]:=41;
end else CanTakeElavotor[i]:=41;
end else
for i:=0 to 9 DO
begin
if CanTake(i,self.DestinationFloor) then
begin
if (self.Direction=Elavotor[i].Direction) or (self.CurrentFloor=1)
or (self.CurrentFloor=40) then
begin
if self.Direction=1 then
if (self.CurrentFloor-Elavotor[i].CurrentFloor)>=0 then
CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor);
if self.Direction=2 then
if (self.CurrentFloor-Elavotor[i].CurrentFloor)<=0 then
CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor);
end
else CanTakeElavotor[i]:=41;
end
else
CanTakeElavotor[i]:=41;
end;
for i:=0 to 9 DO
begin
if CanTakeElavotor[i]<=iTemp then
begin
iTemp:=CanTakeElavotor[i];
j:=i;
end;
Result:=j;
end;
if Result>=41 then
if Elavotor[0].OuterRequestArray.Count<MaxLoad then Result:=0
else Result:=1;
end;
procedure TPerson.SendRequest(CurrentFloor,DestinationFloor:integer);
var Temp:string;
begin
if self.MissionCompleted then exit;
self.PersonStatus:=PersonStatus_Request;
Temp:=inttostr(self.PersonID)+'-'+inttostr(self.DestinationFloor)+':'+Inttostr(self.SelectedElavotorID);
if not Finduser(Floor[CurrentFloor].Requestlist,self.PersonID) then
begin
Elavotor[self.SelectedElavotorID].OuterRequestArray.Add(copy(Temp,0,pos(':',Temp)-1));
Floor[CurrentFloor].Requestlist.Add(Temp);
end;
end;
procedure TSystemControl.Statistic;
var i,j,k,z,h,iDelIdle,DelStat:integer;
Tempstr,str_idle,str_taking,str_Request,str:string;
begin
self.FinishedPersonTotal:=0;
mainform.memo10.Clear; //当前请求乘梯人员
mainform.memo11.Clear; //当前闲留人员
mainform.memo12.Clear; //当前完成乘梯任务的人员
mainform.memo13.Clear; //当前正在乘梯的人员
for i:=0 to self.CurrentPersonTotal-1 DO
if not person[i].MissionCompleted then
case person[i].PersonStatus of
PersonStatus_idle:
begin
person[i].idle_Time:=person[i].idle_Time+1;
str_idle:='第'+Inttostr(person[i].PersonID)+'号乘客已闲留'+Inttostr(Person[i].idle_Time)+'秒';
if mainform.memo13.lines.indexof(str_idle)<0 then
mainform.memo11.lines.Add(str_idle);
end;
PersonStatus_Request:
begin
person[i].Request_Time:=person[i].Request_Time+1;
str_Request:='第'+Inttostr(person[i].PersonID)+'号已等'+Inttostr(Person[i].Request_Time)+'秒'+Inttostr(Person[i].SelectedElavotorID)+'号梯'+Inttostr(Person[i].CurrentFloor)+'楼';
if mainform.memo13.lines.indexof(str_Request)<0 then
mainform.memo10.lines.Add(str_Request);
//动态选择电梯
Person[i].SelectedElavotorID:=Person[i].ChooseElavotor(
Person[i].CurrentFloor,Person[i].DestinationFloor);
finduser(floor[Person[i].CurrentFloor].Requestlist,Person[i].PersonID);
end;
PersonStatus_Taking:
begin
person[i].Taking_Time:=person[i].Taking_Time+1;
str_taking:='第'+Inttostr(person[i].PersonID)+'号乘客已乘坐'+Inttostr(Person[i].Taking_Time)+'秒';
if mainform.memo13.lines.indexof(str_taking)<0 then
mainform.memo13.lines.Add(str_taking);
end;
end else begin
self.FinishedPersonTotal:=self.FinishedPersonTotal+1;
mainform.memo12.Lines.Add('第'+Inttostr(person[i].PersonID)+'号乘客');
end;
mainform.STB1.Panels[0].Text:='当前系统运行时间:'+Inttostr(self.SimTimeTotal)+'秒';
mainform.STB1.Panels[1].Text:='当前系统仿真人数:'+Inttostr(self.CurrentPersonTotal)+'个';
mainform.STB1.Panels[2].Text:='已经完成乘梯任务的人数: '+Inttostr(self.FinishedPersonTotal)+'个';
j:=0;
z:=0;
K:=1;
//检测是否有人完成闲留开始请求
for i:=1 to 40 Do
if Floor[i].Idlelist.Count>0 then
begin
for h:=0 to Floor[i].Idlelist.Count-1 Do
begin
Tempstr:=Floor[i].Idlelist.Strings[h];
j:=Strtoint(copy(Tempstr,0,pos('-',Tempstr)-1));
K:=Strtoint(copy(Tempstr,pos('-',Tempstr)+1,pos(':',Tempstr)-pos('-',Tempstr)-1));
z:=Strtoint(copy(Tempstr,pos(':',Tempstr)+1,Length(Tempstr)-pos(':',Tempstr)+1));
if (self.SimTimeTotal-z)>=k then
begin
person[j].DestinationFloor:=Random(40)+1;
while person[j].DestinationFloor=person[j].CurrentFloor DO
person[j].DestinationFloor:=Random(40)+1;
if (Person[j].MissionCompleted=True) or (person[j].FinishedCount=TakeNum) then
Person[j].DestinationFloor:=1;
person[j].SelectedElavotorID:=person[j].ChooseElavotor(1,person[j].DestinationFloor);
person[j].SendRequest(1,person[j].DestinationFloor);
DelIdle.Add(Tempstr);
end;
end;
//删除当前楼层闲留队列中闲留时间已到的人员
for iDelIdle:=0 to DelIdle.Count-1 Do
if DelIdle.Strings[iDelIdle]<>'' then
begin
K:=Floor[i].Idlelist.IndexOf(DelIdle.Strings[iDelIdle]);
if K>=0 then
Floor[i].Idlelist.Delete(k);
end;
DelIdle.Clear;//清空临时删除队列
end;
//监控电梯运行情况
for i:=0 to 9 DO
begin
if Elavotor[i].Direction=0 then
if Elavotor[i].OuterRequestArray.Count>0 then
begin
Tempstr:=Elavotor[i].OuterRequestArray.Strings[0];
j:=Strtoint(copy(Tempstr,0,pos('-',Tempstr)-1));
Elavotor[i].Direction:=person[j].Direction;
end;
end;
//显示楼层人员停留情况
ShowFloor.RowCount:=12;
ShowFloor.ColCount:=11;
ShowFloor.Cells[0,1]:='等待人数';
ShowFloor.Cells[0,2]:='闲留人数';
ShowFloor.Cells[0,4]:='等待人数';
ShowFloor.Cells[0,5]:='闲留人数';
ShowFloor.Cells[0,7]:='等待人数';
ShowFloor.Cells[0,8]:='闲留人数';
ShowFloor.Cells[0,10]:='等待人数';
ShowFloor.Cells[0,11]:='闲留人数';
z:=0;
k:=1;
for i:=1 to 4 Do
begin
for j:=1 to 10 DO
begin
z:=z+1;
ShowFloor.Cells[j,K-1]:='第'+inttostr(z)+'层楼';
Tempstr:=Inttostr(Floor[z].Requestlist.count)+'个';
Str:=Inttostr(Floor[z].Idlelist.count)+'个';
ShowFloor.Cells[j,k]:=Tempstr;
ShowFloor.Cells[j,k+1]:=str;
end;
K:=K+3;
end;
if self.FinishedPersonTotal=PersonNum then
begin
Application.MessageBox('本次仿真结束!','电梯仿真',0);
mainform.Close;
end;
end;
{ TSystemMonitor }
procedure TSystemMonitor.Execute;
begin
While not self.Terminated Do
begin
Synchronize(self.Monitor);
sleep(1000); //间隔一秒
end;
end;
procedure TSystemMonitor.Monitor;
begin
self.Priority:=tpTimeCritical;
systemcontrol.SimTimeTotal:=systemcontrol.SimTimeTotal+1;
SystemControl.InitAddedPerson;
SystemControl.Statistic;
Application.ProcessMessages;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -