⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 define.pas

📁 模拟电梯系统,有40个楼层,10做电梯,实现全部人和动作,望大家参考,提意见.
💻 PAS
📖 第 1 页 / 共 2 页
字号:
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 + -