?? 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 + -