library RQuickie;

{ Jednoduchý organismus, který jezdí a množí se jak může (= exponenciální nárůst
  populace). Díky zajímavému algoritmu pohybu dokáže rychle obsadit "výhodné"
  oblasti v prostředí a zároveň vysílá velké množství "průzkumníků" do velkého
  okolí.

  Pokud ho umístíte do prostředí bohatého na potravu, tak se postupně "rozleze"
  do všech stran a velmi se přemnoží. Jakmile je ale už jednou rozmnožen
  (několik tisíc jedinců), přežije i v prostředí s velmi malým průměrným
  množstvím potravy na políčko. }

{$R *.RES}

uses
  OrgInterface;

const
  // BEGIN UR
  TargetX = 0;
  TargetY = 1;
  NextMoveKind = 2;
    nmkNear = 0;
    nmkFar = 1;
  ColorValue = 3;
  // END UR

  NearRadius = 10;
  FarRadius = 100;

procedure OrgRun(Organism: IVLFOrganism); stdcall;
var
  AX, AY: Integer;
  I, Radius: Integer;
  Org: string;
begin
  with Organism do
  begin
    if Age = 0 then AllocUR(4);

    { V první generaci se vybere barva celého rodu. }
    if GenCount = 0 then
      SetUR(ColorValue, 128 + Random(128));

    { Trochu zvýšíme hmotnost a energii. }
    if Mass < 20 then
    begin
      Eat(20);
      Build(20)
    end;
    if Energy < 20 then
    begin
      Eat(20);
      Digest(20);
    end;

    { Útočíme na každého, kdo je pod námi a je jiného druhu. Před útokem mu
      rozházíme registry, takže bue mít v hlavě zmatek. }
    Org := OrgAt(0, 0);
    if (Org <> '') and (Org <> Species) then
    begin
      for I := 0 to ForeignAllocedURCount do
        SetForeignUR(I, Random(256));
      Attack;
    end;

    { Ihned po narození nebo při dojezdu na cílové souřadnice se nastaví
      nové cílové souřadnice. Střídavě se nastavují z blízkého a vzdáleného
      okolí organismu. }
    if (Age = 0) or ((X = UR(TargetX)) and (Y = UR(TargetY))) then
    begin
      Radius := 0; // avoid warning
      case UR(NextMoveKind) of
        nmkNear:
        begin
          Radius := NearRadius;
          SetUR(NextMoveKind, nmkFar);
        end;
        nmkFar:
        begin
          Radius := FarRadius;
          SetUR(NextMoveKind, nmkNear);
        end;
      end;

      AX := X + Random(2 * Radius) - Radius;
      if AX < 0 then AX := 0;
      if AX > MaxX then AX := MaxX;
      AY := Y + Random(2 * Radius) - Radius;
      if AY < 0 then AY := 0;
      if AY > MaxY then AY := MaxY;
      SetUR(TargetX, AX);
      SetUR(TargetY, AY);

      { Po narození nastavíme barvu, jinak (tj. při dojezdu na cílové
        souřadnice) zplodíme potomka a nastavíme mu barvové UR. }
      if Age = 0 then
        SetColor(0, UR(ColorValue), UR(ColorValue) div 2)
      else
      begin
        DivCell;
        SetForeignUR(ColorValue, UR(ColorValue));
      end;
    end;

    { pohyb }
    if UR(TargetX) < X then Move(W, 1);
    if UR(TargetX) > X then Move(E, 1);
    if UR(TargetY) < Y then Move(N, 1);
    if UR(TargetY) > Y then Move(S, 1);

  end;
end;

exports
  OrgRequiredVersion,
  OrgRun;

end.
