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

📄 define.pas

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

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