procedure TTreeAnt.SetTurnAroundFlag(ATurnAroundFlag: Boolean);
begin
if FTurnAroundFlag <> ATurnAroundFlag then
FTurnAroundFlag := ATurnAroundFlag;
end;
procedure TTreeAnt.SetHeadDirection(AHeadDirection: Boolean);
begin
if FHeadDirection <> AHeadDirection then
FHeadDirection := AHeadDirection;
end;
procedure TTreeAnt.SetPosition(APosition: Integer);
begin
if FPosition <> APosition then
FPosition := APosition;
end;
procedure TTreeAnt.SetLifeValueUpperLimit(ALifeValue: Integer);
begin
if FLifeValueUpperLimit <> ALifeValue then
FLifeValueUpperLimit := ALifeValue;
end;
procedure TTreeAnt.SetLifeValueLowerLimit(ALifeValue: Integer);
begin
if FLifeValueLowerLimit <> ALifeValue then
FLifeValueLowerLimit := ALifeValue;
end;
procedure TTreeAnt.StepIt();
begin
if FHeadDirection then
Inc(FPosition)
else
Dec(FPosition);
if (FPosition > FLifeValueUpperLimit) or (FPosition < FLifeValueLowerLimit) then
FLiving := False;
end;
procedure TTreeAnt.TurnAround;
begin
FHeadDirection := not FHeadDirection;
end;
procedure TTreeAntMgr.Init;
var
I: Integer;
begin
FAntCnt := 0;
FTimeCnt := 0;
FAntLivingCnt := 0;
FRunning := False;
for I := Low(FTreeNode) to High(FTreeNode) do
begin
FTreeNode[I] := 0;
end;
end;
procedure TTreeAntMgr.SetTreeNodeFlag(APosition: Integer);
begin
FTreeNode[APosition] := 1;
end;
procedure TTreeAntMgr.ResetTreeNodeFlag(APosition: Integer);
begin
FTreeNode[APosition] := 0;
end;
function TTreeAntMgr.GetPositionAntIdx(APosition: Integer): Integer;
var
I: Integer;
begin
Result := -1;
for I := Low(FTreeAnts) to High(FTreeAnts) do
begin
if FTreeAnts[I].Position = APosition then
begin
Result := I;
Break;
end;
end;
end;
function TTreeAntMgr.IsTurnAround(AntIdx: Integer): Boolean;
var
bMiddle: Boolean;
bRight: Boolean;
bLeft: Boolean;
Position: Integer;
NextAntIdx: Integer;
begin
Result := False;
bMiddle := FTreeAnts[AntIdx].HeadDirection;
Position := FTreeAnts[AntIdx].Position;
if bMiddle then
begin
if FTreeNode[Position+2] = 0 then
Exit;
NextAntIdx := GetPositionAntIdx(Position+2);
if NextAntIdx = -1 then Exit;
bRight := FTreeAnts[NextAntIdx].HeadDirection;
if not bRight then // 1 23
begin
Result := True;
Exit;
end;
end
else
begin
if FTreeNode[Position-2] = 0 then
Exit;
NextAntIdx := GetPositionAntIdx(Position-2);
if NextAntIdx = -1 then Exit;
bLeft := FTreeAnts[NextAntIdx].HeadDirection;
if bLeft then // 12 3
begin
Result := True;
Exit;
end;
end;
end;
procedure TTreeAntMgr.EnterTree(TreeAntInitRec: TTreeAntInitRec);
begin
if FAntCnt > High(FTreeAnts) then
Exit;
if TreeAntInitRec.Position > High(FTreeNode) then
Exit;
FTreeAnts[FAntCnt] := TTreeAnt.Create;
FTreeAnts[FAntCnt].HeadDirection := TreeAntInitRec.HeadDirection;
FTreeAnts[FAntCnt].Position := TreeAntInitRec.Position;
FTreeAnts[FAntCnt].LifeValueUpperLimit := TreeAntInitRec.UpperLimit;
FTreeAnts[FAntCnt].LifeValueLowerLimit := TreeAntInitRec.LowerLimit;
//FTreeNode[FTreeAnts[FAntCnt].Position] := 1;
SetTreeNodeFlag(TreeAntInitRec.Position);
Inc(FAntCnt);
end;
procedure TTreeAntMgr.Start;
begin
FTimer.Enabled := True;
FRunning := True;
end;
procedure TTreeAntMgr.Stop;
begin
FTimer.Enabled := False;
FRunning := False;
end;
procedure TTreeAntMgr.SetSpeed(ASpeed: Integer);
begin
if FSpeed <> ASpeed then
begin
FSpeed := ASpeed;
FTimer.Interval := FSpeed;
end;
end;
procedure TTreeAntMgr.TimerRun(Sender: TObject);
var
I: Integer;
begin
Inc(FTimeCnt);
Log('计时:' + IntToStr(FTimeCnt));
LogPosition;
FAntLivingCnt := 0;
for I := Low(FTreeAnts) to High(FTreeAnts) do
begin
if FTreeAnts[I].FLiving then
if FTreeAnts[I].TurnAroundFlag then
begin
FTreeAnts[I].TurnAround;
Log('转向:'+IntToStr(I));
end;
FTreeAnts[I].TurnAroundFlag := IsTurnAround(I);
end;
for I := Low(FTreeAnts) to High(FTreeAnts) do
begin
if not FTreeAnts[I].Living then
begin
Inc(FAntLivingCnt);
if FAntLivingCnt >= FAntCnt then
begin
Stop;
AddTime(0);
Exit;
end;
Continue;
end;
ResetTreeNodeFlag(FTreeAnts[I].Position);
FTreeAnts[I].StepIt;
if FTreeAnts[I].Living then
SetTreeNodeFlag(FTreeAnts[I].Position)
else
begin
Log('离桥:'+IntToStr(I) + ' 时间:' + IntToStr(FTimeCnt));
AddTime(FTimeCnt);
end;
end;
end;