📄 define.pas
字号:
unit Define;
interface
uses
Classes,Forms,Controls,Windows,comctrls,stdctrls,Sysutils,grids,Dialogs;
Const
MaxFloor = 40; //最大楼梯层
MaxPerson = 1000; //最大仿真人数
MaxElavotor = 10; //最大电梯数
ElavotorStatus_Idle = 0; //电梯空闲状态
ElavotorStatus_UP = 1; //电梯上行状态
ElavotorStatus_Down = 2; //电梯下行状态
PersonStatus_idle = 0; //人员停留状态
PersonStatus_Request = 1; //人员请求状态
PersonStatus_Taking = 2; //人员乘梯状态
type
//定义线程对象
TRunThread = class(TThread)
private
ElavotorID:integer;
protected
procedure RuningElavotor; //线程仿真电梯运行
procedure Runing(ElavotorID:integer); //线程仿真电梯运行
procedure Execute; override;
end;
TSystemMonitor = class(TThread)
private
protected
procedure Monitor; //线程仿真电梯运行
procedure Execute; override;
end;
//定义电梯对象
TElavotor = class
private
protected
public
Speed:integer; //速度
Direction:integer; //电梯运行方向 “0=idle" "1=up" "2=down"
MaxLoadCapacity:integer; //电梯最大载客量
CurrentLoadCapacity:integer; //电梯当前载客量
DestFloorLayer:integer; //电梯目标楼层
isFull:Boolean; //电梯满员
nIdleTime:integer; //空闲时间计数器
nBusyTime:integer; //工作时间计数器
CurrentStatus:integer; //电梯当前状态 "idle" "up" "down"
PersonTotal:integer; //总完成承载人数
ID:integer; //电梯编号
CurrentFloor:integer; //电梯当前所处楼层
UpDownTime:integer; //每人上下电梯时间
OSdelaytime:integer; //电梯开关门时间
OuterRequestArray:TStringList; //等待队列 "xx-xx"
InsideRequestArray:TStringList; //等待队列 "12-35"
procedure OpenDoor(DelayTime:integer); //开门
procedure CloseDoor(DelayTime:integer); //关门
Procedure UPrun; //上行
Procedure Downrun; //下行
Procedure Continuerun; //继续运行
Function CheckStop(CurrentFloor:integer):Boolean; //检查当前层是否有人上下
Procedure TakeElavotor(CurrentFloor:integer); //乘梯
end;
//定义人员对象
TPerson = Class
Private
Protected
public
Direction:integer; //请求的方向 "0=idle" "1=Up" "2=Down"
FinishedCount:integer; //目前已乘坐次数
DestinationFloor:integer; //请求目标楼层
CurrentFloor:integer; //目前所处楼层
PersonID:integer; //人员编号
SelectedElavotorID:integer; //选择要乘的电梯编号
PersonStatus:integer; //当前状态 "Request" "idle" "Taking"
idle_Time:integer; //人员停留时间
Request_Time:integer; //人员请求时间
Taking_Time:integer; //人员乘梯时间
MissionCompleted:Boolean; //是否结束仿真任务
Function ChooseElavotor(CurrentFloor,DestinationFloor:integer):integer;//选择合适的电梯
Procedure SendRequest(CurrentFloor,DestinationFloor:integer); //发送乘梯请求
end;
//定义楼层对象
TFloor = class
private
protected
public
Requestlist:TStringList; //请求乘梯队列
Idlelist:TStringList; //空闲队列 "UserID-CurTime-IdleTime"
end;
//定义系统控制对象
TSystemControl = Class
private
protected
public
CurrentPersonTotal:integer; //当前已经到达大厦的人数
FinishedPersonTotal:integer; //当前已经完成乘梯任务的人数
SimTimeTotal:integer; //系统计数器
NewPerson:integer; //新到人数
Procedure Initsystem; //初始化系统
Function InitAddedPerson:integer; //初始化新到来的人对象
Procedure Statistic; //系统实时统计
end;
function Finduser(arraylist:TStringList;userId:integer):Boolean; //寻找队列中是否已经存在该客户
function CanTake(ElavotorID,Destlayer:integer):Boolean; //目标楼层是否可以直接到达
var
Maxload :integer; //电梯最大乘客量
PersonNum:integer; //参与仿真人数
Ontime:integer; //人员到齐时间
ElavotorSpeed:integer; //电梯运行速度
UpDownTime:integer; //上下电梯时间
TakeNum:integer; //乘做电梯次数
Elavotor:array[0..9] of TElavotor; //电梯实例对象
RunThread:array[0..9] of TRunThread; //运行电梯线程实例对象
Floor:array[1..40] of TFloor; //定义楼梯实例对象
Person:array of Tperson; //定义动态人员列表
SystemControl:TSystemControl; //系统控制对象
SystemMonitor:TsystemMonitor; //系统监控线程实例对象
ElavotorTrack:array[0..9] of TTrackBar; //显示电梯进度
Elavotor_idle_Label:array[0..9] of TStaticText; //显示空闲时间
Elavotor_Busy_Label:array[0..9] of TStaticText; //显示运行时间
Elavotor_Memo:array[0..9] of TMemo; //显示电梯内部运载情况
ShowFloor:TstringGrid; //显示楼层人员停留
DelIdle:Tstringlist; //临时删除队列
implementation
uses main;
{ TRunThread }
function Finduser(arraylist:TStringList;userId:integer):Boolean;
var i,j:integer;
Tempstr,str,StrEID,strFloor:string;
begin
Result:=False;
for i:=0 to arraylist.Count-1 Do
begin
Tempstr:=arraylist.Strings[i]; //等待信息
Str:=Copy(Tempstr,0,pos('-',Tempstr)-1); //取得乘客编号
StrEID:=Copy(Tempstr,pos(':',Tempstr)+1,
length(tempstr)-pos(':',Tempstr)+1); //取得所等待的电梯编号
if Strtoint(Str)=userId then //当前乘客是否存在
begin
Result:=True;
if Person[userId].SelectedElavotorID<>Strtoint(StrEID) then //是否改变所乘电梯
begin
strFloor:=copy(Tempstr,0,pos(':',Tempstr)-1);
Elavotor[Strtoint(StrEID)].OuterRequestArray.Delete( //删除不合适等待队列
Elavotor[Strtoint(StrEID)].OuterRequestArray.indexof(strFloor));
Floor[Person[userId].CurrentFloor].Requestlist.Delete(
Floor[Person[userId].CurrentFloor].Requestlist.indexof(Tempstr));
Person[userId].SendRequest(Person[userId].CurrentFloor, //选择另外一个电梯
Person[userId].DestinationFloor);
end;
Exit;
end;
end;
end;
procedure TRunThread.RuningElavotor;
begin
self.Runing(self.ElavotorID);
end;
procedure TRunThread.Runing(ElavotorID: integer);
begin
Elavotor[ElavotorID].Continuerun;
Application.ProcessMessages;
end;
procedure TRunThread.Execute;
begin
while not self.Terminated DO
begin
Synchronize(RuningElavotor);
sleep(1000);
end;
end;
function TSystemControl.InitAddedPerson: integer;
var i,iTemp:integer;
begin
Result:=0;
//人员随机到齐
if self.CurrentPersonTotal>=PersonNum then
begin
Result:=1;
exit;
end else if (PersonNum-self.CurrentPersonTotal)<5 then
begin
Self.NewPerson:=PersonNum-self.CurrentPersonTotal;
end else Self.NewPerson:=Random(5);
if Self.NewPerson = 0 then exit;
iTemp:=self.CurrentPersonTotal+Self.NewPerson;
if iTemp>PersonNum then
begin
Self.NewPerson:=PersonNum + self.CurrentPersonTotal;
iTemp:=PersonNum;
exit;
end;
Setlength(Person,iTemp);
for i:=0 to self.NewPerson-1 Do
try
person[self.CurrentPersonTotal+i]:=Tperson.Create;
person[self.CurrentPersonTotal+i].FinishedCount:=0;
person[self.CurrentPersonTotal+i].Direction:=1;
person[self.CurrentPersonTotal+i].CurrentFloor:=1;
Person[self.CurrentPersonTotal+i].PersonID:=self.CurrentPersonTotal+i;
Person[self.CurrentPersonTotal+i].PersonStatus:=PersonStatus_Request;
Person[self.CurrentPersonTotal+i].Taking_Time:=0;
Person[self.CurrentPersonTotal+i].idle_Time:=0;
Person[self.CurrentPersonTotal+i].Request_Time:=0;
Person[self.CurrentPersonTotal+i].MissionCompleted:=false;
person[self.CurrentPersonTotal+i].DestinationFloor:=Random(40)+1;
while person[self.CurrentPersonTotal+i].DestinationFloor<=1 DO
person[self.CurrentPersonTotal+i].DestinationFloor:=Random(40)+1;
person[self.CurrentPersonTotal+i].SelectedElavotorID:=
person[self.CurrentPersonTotal+i].ChooseElavotor(1,
person[self.CurrentPersonTotal+i].DestinationFloor);
person[self.CurrentPersonTotal+i].SendRequest(1,
person[self.CurrentPersonTotal+i].DestinationFloor);
finally
end;
self.CurrentPersonTotal:=iTemp;
end;
procedure TSystemControl.Initsystem;
var i:integer;
begin
self.SimTimeTotal:=0;
self.CurrentPersonTotal:=0;
DelIdle:=Tstringlist.Create;
systemMonitor:=TsystemMonitor.create(false); //创建系统监控线程
systemMonitor.Suspend;
Randomize;
//初始化电梯对象参数
try
for i:=0 to 9 Do
begin
Elavotor[i]:=TElavotor.Create;
Elavotor[i].ID:=i;
Elavotor[i].Speed :=ElavotorSpeed;
Elavotor[i].MaxLoadCapacity:=Maxload;
Elavotor[i].UpDownTime:=UpDownTime;
Elavotor[i].CurrentLoadCapacity :=0;
Elavotor[i].Direction:=2;
Elavotor[i].DestFloorlayer:=0;
Elavotor[i].OSdelaytime:=1;
Elavotor[i].CurrentStatus:=0;
Elavotor[i].CurrentLoadCapacity :=0;
Elavotor[i].nIdleTime:=0;
Elavotor_idle_Label[i].Caption :=Inttostr(Elavotor[i].nidleTime);
Elavotor[i].nBusyTime:=0;
Elavotor_Busy_Label[i].Caption :=Inttostr(Elavotor[i].nBusyTime);
Elavotor[i].CurrentFloor:=Random(40)+1;
ElavotorTrack[i].Position:=1-Elavotor[i].CurrentFloor;
Elavotor[i].PersonTotal :=0;
Elavotor[i].OuterRequestArray :=TStringList.Create;
Elavotor[i].InsideRequestArray :=TStringList.Create;
RunThread[i]:=TRunThread.Create(false);
RunThread[i].Suspend;
RunThread[i].ElavotorID:= i;
end;
For i:=1 to 40 Do
begin
Floor[i]:=TFloor.Create;
Floor[i].Requestlist:=TStringList.Create;
Floor[i].Idlelist:=TStringList.Create;
end;
finally
end;
end;
{ TElavotor }
function TElavotor.CheckStop(CurrentFloor:integer): Boolean;
var i,j,iDown:integer;
Tempstr,Str:string;
begin
Result:=false;
//判断当前层是否有人下
if (CurrentFloor>40) or (CurrentFloor<1) then exit;
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].MissionCompleted then Continue;
if person[j].DestinationFloor=CurrentFloor then
begin
Result:=True;
Exit;
end;
end;
//判断是否满员
if self.isFull then
begin
Result:=false;
exit;
end;
//如果没有人下,判断是否有人上
iDown:=Floor[CurrentFloor].Requestlist.Count-1;
for i:=0 to iDown Do
if CurrentFloor<>1 then
begin
Tempstr:=Floor[CurrentFloor].Requestlist.Strings[i];
Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
j:=Strtoint(Str);
if not person[j].MissionCompleted then
if person[j].CurrentFloor = CurrentFloor then
begin
Result:=True;
Exit;
end;
end else if (CurrentFloor=1) or (CurrentFloor=40) then
begin
Result:=True;
Exit;
end;
end;
procedure TElavotor.CloseDoor(DelayTime: integer);
begin
self.nidleTime:=self.nidleTime+DelayTime;
Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
end;
procedure TElavotor.Continuerun;
begin
if Self.Direction=1 then self.UPrun
else if Self.Direction=2 then self.Downrun
else if Self.Direction=0 then
begin
self.nidleTime:=self.nidleTime+1;
Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
exit;
end;
end;
procedure TElavotor.Downrun;
begin
if (self.CurrentFloor=1) then
begin
self.Direction:=1;
exit;
end;
Self.CurrentFloor:=self.CurrentFloor-ElavotorSpeed;
if Self.CurrentFloor<=0 then Self.CurrentFloor:=1;
ElavotorTrack[self.ID].Position:=1-self.CurrentFloor;
self.nBusyTime:= self.nBusyTime+1;
Elavotor_Busy_Label[self.ID].Caption :=inttostr(self.nBusyTime);
if not CanTake(self.ID,self.CurrentFloor) then exit; //如果当前楼层不能停,就继续下
self.TakeElavotor(self.CurrentFloor);
end;
procedure TElavotor.OpenDoor(DelayTime: integer);
begin
self.nidleTime:=self.nidleTime+DelayTime;
Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -