Define.pas
上传用户:sipnol
上传日期:2013-03-16
资源大小:318k
文件大小:28k
源码类别:

百货/超市行业

开发平台:

Visual C++

  1. unit Define;
  2. interface
  3. uses
  4.   Classes,Forms,Controls,Windows,comctrls,stdctrls,Sysutils,grids,Dialogs;
  5. Const
  6.    MaxFloor     = 40;      //最大楼梯层
  7.    MaxPerson    = 1000;    //最大仿真人数
  8.    MaxElavotor  = 10;      //最大电梯数
  9.    ElavotorStatus_Idle   = 0;  //电梯空闲状态
  10.    ElavotorStatus_UP     = 1;  //电梯上行状态
  11.    ElavotorStatus_Down   = 2;  //电梯下行状态
  12.    PersonStatus_idle     = 0;  //人员停留状态
  13.    PersonStatus_Request  = 1;  //人员请求状态
  14.    PersonStatus_Taking   = 2;  //人员乘梯状态
  15. type
  16. //定义线程对象
  17.   TRunThread = class(TThread)
  18.      private
  19.        ElavotorID:integer;
  20.      protected
  21.         procedure RuningElavotor; //线程仿真电梯运行
  22.         procedure Runing(ElavotorID:integer); //线程仿真电梯运行
  23.         procedure Execute; override;
  24.   end;
  25.   TSystemMonitor = class(TThread)
  26.      private
  27.      protected
  28.         procedure Monitor; //线程仿真电梯运行
  29.         procedure Execute; override;
  30.   end;
  31. //定义电梯对象
  32.   TElavotor = class
  33.      private
  34.      protected
  35.      public
  36.         Speed:integer;                  //速度
  37.         Direction:integer;              //电梯运行方向 “0=idle" "1=up" "2=down"
  38.         MaxLoadCapacity:integer;        //电梯最大载客量
  39. CurrentLoadCapacity:integer;    //电梯当前载客量
  40.         DestFloorLayer:integer;         //电梯目标楼层
  41.         isFull:Boolean;                 //电梯满员
  42. nIdleTime:integer;              //空闲时间计数器
  43. nBusyTime:integer;              //工作时间计数器
  44.         CurrentStatus:integer;          //电梯当前状态 "idle" "up" "down"
  45. PersonTotal:integer;            //总完成承载人数
  46. ID:integer;                     //电梯编号
  47. CurrentFloor:integer;           //电梯当前所处楼层
  48.         UpDownTime:integer;             //每人上下电梯时间
  49.         OSdelaytime:integer;            //电梯开关门时间
  50.         OuterRequestArray:TStringList;  //等待队列 "xx-xx"
  51.         InsideRequestArray:TStringList; //等待队列 "12-35"
  52.      procedure OpenDoor(DelayTime:integer);  //开门
  53.      procedure CloseDoor(DelayTime:integer); //关门
  54.      Procedure UPrun;                        //上行
  55.      Procedure Downrun;                      //下行
  56.      Procedure Continuerun;                  //继续运行
  57.      Function  CheckStop(CurrentFloor:integer):Boolean;  //检查当前层是否有人上下
  58.      Procedure TakeElavotor(CurrentFloor:integer);      //乘梯
  59.   end;
  60. //定义人员对象
  61.   TPerson = Class
  62.      Private
  63.      Protected
  64.      public
  65. Direction:integer;          //请求的方向   "0=idle" "1=Up" "2=Down"
  66. FinishedCount:integer;       //目前已乘坐次数
  67. DestinationFloor:integer;   //请求目标楼层
  68. CurrentFloor:integer;       //目前所处楼层
  69. PersonID:integer;           //人员编号
  70.         SelectedElavotorID:integer; //选择要乘的电梯编号
  71.         PersonStatus:integer;       //当前状态 "Request" "idle" "Taking"
  72.         idle_Time:integer;          //人员停留时间
  73.         Request_Time:integer;       //人员请求时间
  74.         Taking_Time:integer;        //人员乘梯时间
  75.         MissionCompleted:Boolean;       //是否结束仿真任务
  76.       Function ChooseElavotor(CurrentFloor,DestinationFloor:integer):integer;//选择合适的电梯
  77.       Procedure SendRequest(CurrentFloor,DestinationFloor:integer);       //发送乘梯请求
  78.   end;
  79. //定义楼层对象
  80.   TFloor = class
  81.      private
  82.      protected
  83.      public
  84.         Requestlist:TStringList;       //请求乘梯队列
  85.         Idlelist:TStringList;          //空闲队列 "UserID-CurTime-IdleTime"
  86.    end;
  87. //定义系统控制对象
  88.   TSystemControl = Class
  89.      private
  90.      protected
  91.      public
  92.         CurrentPersonTotal:integer;           //当前已经到达大厦的人数
  93.         FinishedPersonTotal:integer;          //当前已经完成乘梯任务的人数
  94.         SimTimeTotal:integer;                 //系统计数器
  95.         NewPerson:integer;                    //新到人数
  96.        Procedure Initsystem;                 //初始化系统
  97.        Function InitAddedPerson:integer;     //初始化新到来的人对象
  98.        Procedure Statistic;                  //系统实时统计
  99.    end;
  100.    
  101.    function Finduser(arraylist:TStringList;userId:integer):Boolean; //寻找队列中是否已经存在该客户
  102.    function CanTake(ElavotorID,Destlayer:integer):Boolean;   //目标楼层是否可以直接到达
  103. var
  104.    Maxload :integer;                     //电梯最大乘客量
  105.    PersonNum:integer;                    //参与仿真人数
  106.    Ontime:integer;                       //人员到齐时间
  107.    ElavotorSpeed:integer;                //电梯运行速度
  108.    UpDownTime:integer;                   //上下电梯时间
  109.    TakeNum:integer;                      //乘做电梯次数
  110.    Elavotor:array[0..9] of TElavotor;    //电梯实例对象
  111.    RunThread:array[0..9] of TRunThread;  //运行电梯线程实例对象
  112.    Floor:array[1..40] of TFloor;         //定义楼梯实例对象
  113.    Person:array of Tperson;              //定义动态人员列表
  114.    SystemControl:TSystemControl;         //系统控制对象
  115.    SystemMonitor:TsystemMonitor;         //系统监控线程实例对象
  116.    ElavotorTrack:array[0..9] of TTrackBar;           //显示电梯进度
  117.    Elavotor_idle_Label:array[0..9] of TStaticText;   //显示空闲时间
  118.    Elavotor_Busy_Label:array[0..9] of TStaticText;   //显示运行时间
  119.    Elavotor_Memo:array[0..9] of TMemo;               //显示电梯内部运载情况
  120.    ShowFloor:TstringGrid;                            //显示楼层人员停留
  121.    DelIdle:Tstringlist;                              //临时删除队列
  122. implementation
  123. uses main;
  124. { TRunThread }
  125. function Finduser(arraylist:TStringList;userId:integer):Boolean;
  126. var i,j:integer;
  127.     Tempstr,str,StrEID,strFloor:string;
  128. begin
  129.    Result:=False;
  130.    for i:=0 to arraylist.Count-1 Do
  131.      begin
  132.        Tempstr:=arraylist.Strings[i];           //等待信息
  133.        Str:=Copy(Tempstr,0,pos('-',Tempstr)-1); //取得乘客编号
  134.        StrEID:=Copy(Tempstr,pos(':',Tempstr)+1,
  135.          length(tempstr)-pos(':',Tempstr)+1);   //取得所等待的电梯编号
  136.        if Strtoint(Str)=userId then             //当前乘客是否存在
  137.          begin
  138.            Result:=True;
  139.            if Person[userId].SelectedElavotorID<>Strtoint(StrEID) then //是否改变所乘电梯
  140.               begin
  141.                 strFloor:=copy(Tempstr,0,pos(':',Tempstr)-1);
  142.                 Elavotor[Strtoint(StrEID)].OuterRequestArray.Delete(            //删除不合适等待队列
  143.                   Elavotor[Strtoint(StrEID)].OuterRequestArray.indexof(strFloor));
  144.                 Floor[Person[userId].CurrentFloor].Requestlist.Delete(
  145.                   Floor[Person[userId].CurrentFloor].Requestlist.indexof(Tempstr));
  146.                 Person[userId].SendRequest(Person[userId].CurrentFloor,        //选择另外一个电梯
  147.                    Person[userId].DestinationFloor);
  148.               end;
  149.            Exit;
  150.          end;
  151.      end;
  152. end;
  153. procedure TRunThread.RuningElavotor;
  154. begin
  155.    self.Runing(self.ElavotorID);
  156. end;
  157. procedure TRunThread.Runing(ElavotorID: integer);
  158. begin
  159.    Elavotor[ElavotorID].Continuerun;
  160.    Application.ProcessMessages;
  161. end;
  162. procedure TRunThread.Execute;
  163. begin
  164.   while not self.Terminated DO
  165.     begin
  166.        Synchronize(RuningElavotor);
  167.        sleep(1000);
  168.     end;
  169. end;
  170. function TSystemControl.InitAddedPerson: integer;
  171. var i,iTemp:integer;
  172. begin
  173.   Result:=0;
  174.   //人员随机到齐
  175.   if self.CurrentPersonTotal>=PersonNum then
  176.     begin
  177.       Result:=1;
  178.       exit;
  179.     end else if (PersonNum-self.CurrentPersonTotal)<5 then
  180.       begin
  181.         Self.NewPerson:=PersonNum-self.CurrentPersonTotal;
  182.       end else Self.NewPerson:=Random(5);
  183.      if Self.NewPerson = 0 then exit;
  184.        iTemp:=self.CurrentPersonTotal+Self.NewPerson;
  185.        if iTemp>PersonNum then
  186.           begin
  187.             Self.NewPerson:=PersonNum + self.CurrentPersonTotal;
  188.             iTemp:=PersonNum;
  189.             exit;
  190.           end;
  191.   Setlength(Person,iTemp);
  192.   for i:=0 to self.NewPerson-1 Do
  193.    try
  194.       person[self.CurrentPersonTotal+i]:=Tperson.Create;
  195.       person[self.CurrentPersonTotal+i].FinishedCount:=0;
  196.       person[self.CurrentPersonTotal+i].Direction:=1;
  197.       person[self.CurrentPersonTotal+i].CurrentFloor:=1;
  198.       Person[self.CurrentPersonTotal+i].PersonID:=self.CurrentPersonTotal+i;
  199.       Person[self.CurrentPersonTotal+i].PersonStatus:=PersonStatus_Request;
  200.       Person[self.CurrentPersonTotal+i].Taking_Time:=0;
  201.       Person[self.CurrentPersonTotal+i].idle_Time:=0;
  202.       Person[self.CurrentPersonTotal+i].Request_Time:=0;
  203.       Person[self.CurrentPersonTotal+i].MissionCompleted:=false;
  204.       person[self.CurrentPersonTotal+i].DestinationFloor:=Random(40)+1;
  205.       while person[self.CurrentPersonTotal+i].DestinationFloor<=1 DO
  206.             person[self.CurrentPersonTotal+i].DestinationFloor:=Random(40)+1;
  207.       person[self.CurrentPersonTotal+i].SelectedElavotorID:=
  208.          person[self.CurrentPersonTotal+i].ChooseElavotor(1,
  209.           person[self.CurrentPersonTotal+i].DestinationFloor);
  210.       person[self.CurrentPersonTotal+i].SendRequest(1,
  211.         person[self.CurrentPersonTotal+i].DestinationFloor);
  212.     finally
  213.     end;
  214.      self.CurrentPersonTotal:=iTemp;
  215. end;
  216. procedure TSystemControl.Initsystem;
  217. var i:integer;
  218. begin
  219.   self.SimTimeTotal:=0;
  220.   self.CurrentPersonTotal:=0;
  221.   DelIdle:=Tstringlist.Create;
  222.   systemMonitor:=TsystemMonitor.create(false); //创建系统监控线程
  223.   systemMonitor.Suspend;
  224.   Randomize;
  225.   //初始化电梯对象参数
  226.    try
  227.     for i:=0 to 9 Do
  228.       begin
  229.            Elavotor[i]:=TElavotor.Create;
  230.            Elavotor[i].ID:=i;
  231.            Elavotor[i].Speed :=ElavotorSpeed;
  232.            Elavotor[i].MaxLoadCapacity:=Maxload;
  233.            Elavotor[i].UpDownTime:=UpDownTime;
  234.            Elavotor[i].CurrentLoadCapacity :=0;
  235.            Elavotor[i].Direction:=2;
  236.            Elavotor[i].DestFloorlayer:=0;
  237.            Elavotor[i].OSdelaytime:=1;
  238.            Elavotor[i].CurrentStatus:=0;
  239.            Elavotor[i].CurrentLoadCapacity :=0;
  240.            Elavotor[i].nIdleTime:=0;
  241.            Elavotor_idle_Label[i].Caption :=Inttostr(Elavotor[i].nidleTime);
  242.            Elavotor[i].nBusyTime:=0;
  243.            Elavotor_Busy_Label[i].Caption :=Inttostr(Elavotor[i].nBusyTime);
  244.            Elavotor[i].CurrentFloor:=Random(40)+1;
  245.            ElavotorTrack[i].Position:=1-Elavotor[i].CurrentFloor;
  246.            Elavotor[i].PersonTotal :=0;
  247.            Elavotor[i].OuterRequestArray :=TStringList.Create;
  248.            Elavotor[i].InsideRequestArray :=TStringList.Create;
  249.            RunThread[i]:=TRunThread.Create(false);
  250.            RunThread[i].Suspend;
  251.            RunThread[i].ElavotorID:= i;
  252.       end;
  253.       For i:=1 to 40 Do
  254.          begin
  255.           Floor[i]:=TFloor.Create;
  256.           Floor[i].Requestlist:=TStringList.Create;
  257.           Floor[i].Idlelist:=TStringList.Create;
  258.          end;
  259.    finally
  260.    end;
  261. end;
  262. { TElavotor }
  263. function TElavotor.CheckStop(CurrentFloor:integer): Boolean;
  264. var i,j,iDown:integer;
  265.     Tempstr,Str:string;
  266. begin
  267.    Result:=false;
  268.    //判断当前层是否有人下
  269.    if (CurrentFloor>40) or (CurrentFloor<1) then exit;
  270.    iDown:=self.InsideRequestArray.Count-1;
  271.    for i:=0 to iDown Do
  272.      begin
  273.        Tempstr:=self.InsideRequestArray.Strings[i];
  274.        Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
  275.        j:=Strtoint(Str);
  276.        if Person[j].MissionCompleted then Continue;
  277.        if person[j].DestinationFloor=CurrentFloor then
  278.          begin
  279.            Result:=True;
  280.            Exit;
  281.          end;
  282.      end;
  283.    //判断是否满员
  284.    if self.isFull then
  285.      begin
  286.        Result:=false;
  287.        exit;
  288.      end;
  289.    //如果没有人下,判断是否有人上
  290.    iDown:=Floor[CurrentFloor].Requestlist.Count-1;
  291.     for i:=0 to iDown Do
  292.       if CurrentFloor<>1 then
  293.         begin
  294.           Tempstr:=Floor[CurrentFloor].Requestlist.Strings[i];
  295.           Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
  296.           j:=Strtoint(Str);
  297.           if not person[j].MissionCompleted then
  298.           if person[j].CurrentFloor = CurrentFloor then
  299.            begin
  300.              Result:=True;
  301.              Exit;
  302.            end;
  303.         end else if (CurrentFloor=1) or (CurrentFloor=40) then
  304.            begin
  305.              Result:=True;
  306.              Exit;
  307.            end;
  308. end;
  309. procedure TElavotor.CloseDoor(DelayTime: integer);
  310. begin
  311.   self.nidleTime:=self.nidleTime+DelayTime;
  312.   Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
  313. end;
  314. procedure TElavotor.Continuerun;
  315. begin
  316.    if Self.Direction=1 then self.UPrun
  317.       else if Self.Direction=2 then self.Downrun
  318.         else if Self.Direction=0 then
  319.                    begin
  320.                      self.nidleTime:=self.nidleTime+1;
  321.                      Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
  322.                      exit;
  323.                    end;
  324. end;
  325. procedure TElavotor.Downrun;
  326. begin
  327.   if (self.CurrentFloor=1) then
  328.       begin
  329.          self.Direction:=1;
  330.          exit;
  331.       end;
  332.   Self.CurrentFloor:=self.CurrentFloor-ElavotorSpeed;
  333.   if Self.CurrentFloor<=0 then  Self.CurrentFloor:=1;
  334.   ElavotorTrack[self.ID].Position:=1-self.CurrentFloor;
  335.   self.nBusyTime:= self.nBusyTime+1;
  336.   Elavotor_Busy_Label[self.ID].Caption :=inttostr(self.nBusyTime);
  337.   if not CanTake(self.ID,self.CurrentFloor) then exit;  //如果当前楼层不能停,就继续下
  338.   self.TakeElavotor(self.CurrentFloor);
  339. end;
  340. procedure TElavotor.OpenDoor(DelayTime: integer);
  341. begin
  342.     self.nidleTime:=self.nidleTime+DelayTime;
  343.     Elavotor_idle_Label[self.ID].Caption :=inttostr(self.nidleTime);
  344. end;
  345. procedure TElavotor.TakeElavotor(CurrentFloor:integer);
  346. var i,j,k,iDown,MaxDest:integer;
  347.     Tempstr,str,AddStr:string;
  348.     Del:TstringList;
  349.     LockThread:TThreadlist;
  350. begin
  351.    LockThread:=TThreadlist.Create;
  352.    LockThread.Add(Floor[CurrentFloor].Requestlist); //加入锁定共享数据列表
  353.    LockThread.Add(Floor[CurrentFloor].Idlelist);
  354.    LockThread.Add(self.OuterRequestArray);
  355.    LockThread.LockList;                          //锁定共享数据对象
  356.    self.Speed:=ElavotorSpeed;
  357.    self.MaxLoadCapacity:=self.InsideRequestArray.Count;
  358.    Del:=Tstringlist.Create;
  359.    if (CurrentFloor>40) or (CurrentFloor<1) then exit;
  360.    if self.CheckStop(CurrentFloor) then
  361.      begin
  362.        //当前层有人下
  363.        iDown:=self.InsideRequestArray.Count-1;
  364.         for i:=0 to iDown Do
  365.           begin
  366.              Tempstr:=self.InsideRequestArray.Strings[i];
  367.              Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
  368.              j:=Strtoint(Str);
  369.              if person[j].DestinationFloor=CurrentFloor then
  370.                 begin
  371.                  if person[j].FinishedCount=TakeNum+1 then
  372.                    begin
  373.                      person[j].MissionCompleted:=true;
  374.                      Continue;
  375.                    end;
  376.                    person[j].CurrentFloor:=CurrentFloor;
  377.                    person[j].SelectedElavotorID:=0;
  378.                    person[j].FinishedCount:=person[j].FinishedCount+1;
  379.                    person[j].PersonStatus:=PersonStatus_idle;
  380.                    Del.Add(Tempstr);
  381.                    K:=Elavotor_Memo[self.ID].Lines.IndexOf(Tempstr);
  382.                    if k>=0 then
  383.                    Elavotor_Memo[self.ID].Lines.Delete(k);
  384.                    k:=Random(100)+20;
  385.                    Addstr:=inttostr(j)+'-'+inttostr(systemControl.SimTimeTotal)+':'+inttostr(k);
  386.                    Floor[CurrentFloor].Idlelist.Add(Addstr); //加入闲置队列UserID-basetime:idletime
  387.                 end;
  388.            end;
  389.            //删除当前楼层等待队列中以上电梯的人员
  390.              for i:=0 to Del.Count-1 Do
  391.               if Del.Strings[i]<>'' then
  392.                 begin
  393.                    k:=self.InsideRequestArray.IndexOf(Del.Strings[i]);
  394.                    if k>=0 then
  395.                    self.InsideRequestArray.Delete(k);
  396.                 end;
  397.          //当前层有人上
  398.          iDown:= Floor[CurrentFloor].Requestlist.Count-1;                        //计算当前楼层等待人数
  399.          Del.Clear;
  400.             for i:=0 to iDown  Do                                                 //判断等待队列中每个人是否要上当前电梯
  401.               begin
  402.                 Tempstr:=Floor[CurrentFloor].Requestlist.Strings[i];
  403.                 Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);
  404.                 j:=Strtoint(Str);
  405.                 if person[j].CurrentFloor<>self.CurrentFloor then Continue else  //是否电梯到达乘客当前楼层
  406.                  if person[j].SelectedElavotorID = Self.ID then
  407.                   begin
  408.                     if self.CurrentFloor=1 then self.Direction:=1;
  409.                     if self.CurrentFloor=40 then self.Direction:=2;
  410.                     if self.CurrentLoadCapacity=MaxLoad then                     //电梯是否已经满员
  411.                        begin
  412.                          self.isFull:=true;
  413.                          Break;
  414.                        end;
  415.                     self.CurrentLoadCapacity:=self.CurrentLoadCapacity+1;       //增加当前乘客
  416.                     Addstr:=inttostr(j)+'-'+inttostr(Person[j].DestinationFloor);
  417.                     self.InsideRequestArray.Add(Addstr);                        //把当前乘客加入内部乘梯队列
  418.                     Elavotor_Memo[self.ID].Lines.Add(Addstr);
  419.                     k:=self.OuterRequestArray.IndexOf(Addstr);
  420.                     if k>=0 then
  421.                        Elavotor[self.ID].OuterRequestArray.Delete(k);           //删除当前乘客在电梯外的等待队列信息
  422.                     person[j].PersonStatus:=PersonStatus_Taking;                //置上当前电梯的人的状态为乘做
  423.                     Del.Add(Tempstr);
  424.                   end;
  425.               end;
  426.            //删除当前楼层等待队列中以上电梯的人员
  427.              for i:=0 to Del.Count-1 Do
  428.               if Del.Strings[i]<>'' then
  429.                 begin
  430.                   K:=Floor[CurrentFloor].Requestlist.IndexOf(Del.Strings[i]);
  431.                   if k>=0 then
  432.                   Floor[CurrentFloor].Requestlist.Delete(K);
  433.                 end;
  434.              Del.Free;
  435.          //改变电梯目标楼层
  436.           MaxDest:=Self.DestFloorLayer;
  437.           iDown:= self.InsideRequestArray.Count-1;
  438.          if (self.CurrentFloor<>1) or (self.CurrentFloor<>40) then
  439.            for i:=0 to iDown Do
  440.              begin
  441.                Tempstr:=self.InsideRequestArray.Strings[i];
  442.                Str:=Copy(Tempstr,0,pos('-',Tempstr)-1);      //UserID-DestFloor
  443.                j:=Strtoint(Str);                             //取得乘客编号
  444.                k:=strtoint(copy(Tempstr,pos('-',Tempstr)+1,length(Tempstr)-pos('-',Tempstr)+1));
  445.                if self.Direction=Person[j].Direction then
  446.                   if MaxDest<k then MaxDest:=k;               //电梯到达的最大楼层
  447.              end;
  448.           Self.DestFloorLayer:=MaxDest;
  449.      end;
  450.     LockThread.UnlockList;
  451.     LockThread.Free;
  452. end;
  453. procedure TElavotor.UPrun;
  454. begin
  455.    if (self.CurrentFloor=40) then
  456.         begin
  457.           self.Direction:=2;
  458.           exit;
  459.         end;
  460.    self.CurrentFloor:=self.CurrentFloor+ElavotorSpeed;
  461.    if Self.CurrentFloor>40 then  Self.CurrentFloor:=40;
  462.    self.nBusyTime:=self.nBusyTime+1;
  463.    ElavotorTrack[self.ID].Position:=1-self.CurrentFloor;
  464.    Elavotor_Busy_Label[self.ID].Caption :=inttostr(self.nBusyTime);
  465.    if not CanTake(self.ID,self.CurrentFloor) then exit;         //如果当前楼层不能停,就继续上
  466.    self.TakeElavotor(Self.CurrentFloor);
  467. end;
  468. { TPerson }
  469. function CanTake(ElavotorID,Destlayer: integer):Boolean;
  470. begin
  471.   Result:=false;
  472.   case ElavotorID of
  473.     0,1:begin Result:=true; exit; end;
  474.     2,3:begin if (Destlayer=1) or (Destlayer>=25) and (Destlayer<=40) then Result:=true else Result:=false; exit;end;
  475.     4,5:begin if Destlayer<=25 then Result:=true; exit;end;
  476.     6,7:begin if (Destlayer=1) or (Destlayer>=2) and (Destlayer<=40) then
  477.             if (Destlayer mod 2)=0 then Result:=true else Result:=false; exit;end;
  478.     8,9:begin if (Destlayer=1) or (Destlayer<=25) and (Destlayer<=39) then
  479.             if not ((Destlayer mod 2)=0) then Result:=true else Result:=false; exit; end;
  480.   end;
  481. end;
  482. function TPerson.ChooseElavotor(CurrentFloor,DestinationFloor: integer): integer;
  483. var i,j,iTemp:integer;
  484.     CanTakeElavotor:array[0..9] of integer;
  485. begin
  486.   Result:=0;
  487.   iTemp:=41;
  488.   if self.CurrentFloor=1 then
  489.     begin
  490.      for i:=0 to 9 DO
  491.       if CanTake(i,self.DestinationFloor) then
  492.          begin
  493.             if Elavotor[i].Direction=2 then
  494.                if Elavotor[i].OuterRequestArray.Count<Maxload then
  495.                   CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor)
  496.                else CanTakeElavotor[i]:=41
  497.              else CanTakeElavotor[i]:=41;
  498.          end else CanTakeElavotor[i]:=41;
  499.     end else if self.CurrentFloor=40 then
  500.      begin
  501.       for i:=0 to 9 DO
  502.        if CanTake(i,self.DestinationFloor) then
  503.          begin
  504.             if Elavotor[i].Direction=1 then
  505.                CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor)
  506.              else CanTakeElavotor[i]:=41;
  507.          end else CanTakeElavotor[i]:=41;
  508.      end else
  509.        for i:=0 to 9 DO
  510.           begin
  511.             if CanTake(i,self.DestinationFloor) then
  512.                begin
  513.                  if (self.Direction=Elavotor[i].Direction) or (self.CurrentFloor=1)
  514.                     or (self.CurrentFloor=40) then
  515.                       begin
  516.                         if self.Direction=1 then
  517.                          if (self.CurrentFloor-Elavotor[i].CurrentFloor)>=0 then
  518.                             CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor);
  519.                         if self.Direction=2 then
  520.                          if (self.CurrentFloor-Elavotor[i].CurrentFloor)<=0 then
  521.                             CanTakeElavotor[i]:=ABS(self.CurrentFloor-Elavotor[i].CurrentFloor);
  522.                       end
  523.                  else CanTakeElavotor[i]:=41;
  524.                end
  525.             else
  526.                CanTakeElavotor[i]:=41;
  527.        end;
  528.   for i:=0 to 9 DO
  529.    begin
  530.     if CanTakeElavotor[i]<=iTemp then
  531.        begin
  532.          iTemp:=CanTakeElavotor[i];
  533.          j:=i;
  534.        end;
  535.          Result:=j;
  536.    end;
  537.   if Result>=41 then
  538.      if Elavotor[0].OuterRequestArray.Count<MaxLoad then  Result:=0
  539.      else Result:=1;
  540. end;
  541. procedure TPerson.SendRequest(CurrentFloor,DestinationFloor:integer);
  542. var Temp:string;
  543. begin
  544.    if self.MissionCompleted then exit;
  545.    self.PersonStatus:=PersonStatus_Request;
  546.    Temp:=inttostr(self.PersonID)+'-'+inttostr(self.DestinationFloor)+':'+Inttostr(self.SelectedElavotorID);
  547.    if not Finduser(Floor[CurrentFloor].Requestlist,self.PersonID) then
  548.       begin
  549.           Elavotor[self.SelectedElavotorID].OuterRequestArray.Add(copy(Temp,0,pos(':',Temp)-1));
  550.           Floor[CurrentFloor].Requestlist.Add(Temp);
  551.       end;
  552. end;
  553. procedure TSystemControl.Statistic;
  554. var i,j,k,z,h,iDelIdle,DelStat:integer;
  555.     Tempstr,str_idle,str_taking,str_Request,str:string;
  556. begin
  557.    self.FinishedPersonTotal:=0;
  558.    mainform.memo10.Clear;  //当前请求乘梯人员
  559.    mainform.memo11.Clear;  //当前闲留人员
  560.    mainform.memo12.Clear;  //当前完成乘梯任务的人员
  561.    mainform.memo13.Clear;  //当前正在乘梯的人员
  562.    for i:=0 to self.CurrentPersonTotal-1 DO
  563.       if not person[i].MissionCompleted then
  564.          case person[i].PersonStatus of
  565.              PersonStatus_idle:
  566.                 begin
  567.                    person[i].idle_Time:=person[i].idle_Time+1;
  568.                    str_idle:='第'+Inttostr(person[i].PersonID)+'号乘客已闲留'+Inttostr(Person[i].idle_Time)+'秒';
  569.                    if mainform.memo13.lines.indexof(str_idle)<0 then
  570.                    mainform.memo11.lines.Add(str_idle);
  571.                 end;
  572.              PersonStatus_Request:
  573.                 begin
  574.                    person[i].Request_Time:=person[i].Request_Time+1;
  575.                    str_Request:='第'+Inttostr(person[i].PersonID)+'号已等'+Inttostr(Person[i].Request_Time)+'秒'+Inttostr(Person[i].SelectedElavotorID)+'号梯'+Inttostr(Person[i].CurrentFloor)+'楼';
  576.                    if mainform.memo13.lines.indexof(str_Request)<0 then
  577.                    mainform.memo10.lines.Add(str_Request);
  578.                    //动态选择电梯
  579.                    Person[i].SelectedElavotorID:=Person[i].ChooseElavotor(
  580.                         Person[i].CurrentFloor,Person[i].DestinationFloor);
  581.                    finduser(floor[Person[i].CurrentFloor].Requestlist,Person[i].PersonID);
  582.                 end;
  583.              PersonStatus_Taking:
  584.                 begin
  585.                    person[i].Taking_Time:=person[i].Taking_Time+1;
  586.                    str_taking:='第'+Inttostr(person[i].PersonID)+'号乘客已乘坐'+Inttostr(Person[i].Taking_Time)+'秒';
  587.                    if mainform.memo13.lines.indexof(str_taking)<0 then
  588.                    mainform.memo13.lines.Add(str_taking);
  589.                 end;
  590.           end else begin
  591.                self.FinishedPersonTotal:=self.FinishedPersonTotal+1;
  592.                mainform.memo12.Lines.Add('第'+Inttostr(person[i].PersonID)+'号乘客');
  593.             end;
  594.    mainform.STB1.Panels[0].Text:='当前系统运行时间:'+Inttostr(self.SimTimeTotal)+'秒';
  595.    mainform.STB1.Panels[1].Text:='当前系统仿真人数:'+Inttostr(self.CurrentPersonTotal)+'个';
  596.    mainform.STB1.Panels[2].Text:='已经完成乘梯任务的人数: '+Inttostr(self.FinishedPersonTotal)+'个';
  597.   j:=0;
  598.   z:=0;
  599.   K:=1;
  600. //检测是否有人完成闲留开始请求
  601.   for i:=1 to 40 Do
  602.    if Floor[i].Idlelist.Count>0 then
  603.      begin
  604.         for h:=0 to Floor[i].Idlelist.Count-1 Do
  605.           begin
  606.             Tempstr:=Floor[i].Idlelist.Strings[h];
  607.             j:=Strtoint(copy(Tempstr,0,pos('-',Tempstr)-1));
  608.             K:=Strtoint(copy(Tempstr,pos('-',Tempstr)+1,pos(':',Tempstr)-pos('-',Tempstr)-1));
  609.             z:=Strtoint(copy(Tempstr,pos(':',Tempstr)+1,Length(Tempstr)-pos(':',Tempstr)+1));
  610.             if (self.SimTimeTotal-z)>=k then
  611.               begin
  612.                 person[j].DestinationFloor:=Random(40)+1;
  613.                 while person[j].DestinationFloor=person[j].CurrentFloor DO
  614.                       person[j].DestinationFloor:=Random(40)+1;
  615.                  if (Person[j].MissionCompleted=True) or (person[j].FinishedCount=TakeNum) then
  616.                     Person[j].DestinationFloor:=1;
  617.                  person[j].SelectedElavotorID:=person[j].ChooseElavotor(1,person[j].DestinationFloor);
  618.                  person[j].SendRequest(1,person[j].DestinationFloor);
  619.                  DelIdle.Add(Tempstr);
  620.               end;
  621.           end;
  622.        //删除当前楼层闲留队列中闲留时间已到的人员
  623.         for iDelIdle:=0 to DelIdle.Count-1 Do
  624.            if DelIdle.Strings[iDelIdle]<>'' then
  625.               begin
  626.                  K:=Floor[i].Idlelist.IndexOf(DelIdle.Strings[iDelIdle]);
  627.                  if K>=0 then
  628.                  Floor[i].Idlelist.Delete(k);
  629.               end;
  630.         DelIdle.Clear;//清空临时删除队列
  631.      end;
  632.  //监控电梯运行情况
  633.     for i:=0 to 9 DO
  634.      begin
  635.        if Elavotor[i].Direction=0 then
  636.           if Elavotor[i].OuterRequestArray.Count>0 then
  637.                begin
  638.                   Tempstr:=Elavotor[i].OuterRequestArray.Strings[0];
  639.                   j:=Strtoint(copy(Tempstr,0,pos('-',Tempstr)-1));
  640.                   Elavotor[i].Direction:=person[j].Direction;
  641.                end;
  642.      end;
  643.   //显示楼层人员停留情况
  644.   ShowFloor.RowCount:=12;
  645.   ShowFloor.ColCount:=11;
  646.   ShowFloor.Cells[0,1]:='等待人数';
  647.   ShowFloor.Cells[0,2]:='闲留人数';
  648.   ShowFloor.Cells[0,4]:='等待人数';
  649.   ShowFloor.Cells[0,5]:='闲留人数';
  650.   ShowFloor.Cells[0,7]:='等待人数';
  651.   ShowFloor.Cells[0,8]:='闲留人数';
  652.   ShowFloor.Cells[0,10]:='等待人数';
  653.   ShowFloor.Cells[0,11]:='闲留人数';
  654.    z:=0;
  655.    k:=1;
  656.    for i:=1 to 4 Do
  657.       begin
  658.         for j:=1 to 10 DO
  659.            begin
  660.              z:=z+1;
  661.              ShowFloor.Cells[j,K-1]:='第'+inttostr(z)+'层楼';
  662.              Tempstr:=Inttostr(Floor[z].Requestlist.count)+'个';
  663.              Str:=Inttostr(Floor[z].Idlelist.count)+'个';
  664.              ShowFloor.Cells[j,k]:=Tempstr;
  665.              ShowFloor.Cells[j,k+1]:=str;
  666.            end;
  667.         K:=K+3;
  668.       end;
  669.    if self.FinishedPersonTotal=PersonNum then
  670.      begin
  671.       Application.MessageBox('本次仿真结束!','电梯仿真',0);
  672.       mainform.Close;
  673.      end;
  674. end;
  675. { TSystemMonitor }
  676. procedure TSystemMonitor.Execute;
  677. begin
  678.    While not self.Terminated Do
  679.      begin
  680.        Synchronize(self.Monitor);
  681.        sleep(1000);  //间隔一秒
  682.      end;
  683. end;
  684. procedure TSystemMonitor.Monitor;
  685. begin
  686.     self.Priority:=tpTimeCritical;
  687.     systemcontrol.SimTimeTotal:=systemcontrol.SimTimeTotal+1;
  688.     SystemControl.InitAddedPerson;
  689.     SystemControl.Statistic;
  690.     Application.ProcessMessages;
  691. end;
  692. end.